How to format a duration in years and months? - node.js

I'm using node.js w/ moment.js for formatting times. I want to get a patient's age formatted in months and years. Here's what I've got so far:
patient: {
...
birthDate: moment('Dec 15, 2009'),
getAgeString: function() {
var age = moment.duration(moment() - this.birthDate);
return util.format('%d years, %d months', age.years(), age.months());
}
}
The getAgeString function gives me back 3 years, 1 months, which is pretty close to what I want, except I'd like it to be pluralized properly. As far as I can tell, moment doesn't offer proper pluralization for durations.
this.birthDate.fromNow(true) is "smart" but it doesn't seem to offer any customization options as to what gets displayed.
Can I get moment.js to do what I want, or is there a better time library for node?
This will have to do for now:
getAgeString: function() {
var age = moment.duration(moment() - this.birthDate);
var years = age.years(), months = age.months();
return util.format('%d year%s, %d month%s', years, years === 1 ? '' : 's', months, months === 1 ? '' : 's');
}

The words that you are looking to pluralize properly appear to be string literals in your own code, and not based on the formatting module. You could do a conditional age.years() or age.months() are equal to 1. If they are, use the strings "year" or "month", otherwise use "years" or "months".

Related

Nodejs change time at date type after getting from Mongodb

I wanted to change time at date type which returning from mongodb with custom time like below
"2021-05-26T00:00:00.000Z"
to
"2021-05-26T10:20:00.000Z"
I wanted to change time from a variable at the date, so my technique was split this date with "T" then get time part and change it with custom time
let splitedTime = timev[0].validFrom.toString().split()[0];
let customTime = "10:20:00.000Z";
let finalTime = splitedTime + customTime;
but this split not working this giving me date like this "Wed May 26 2021 06:00:00 GM". Can you please help me for this?
Working with Date
Whilst I understand your logic of converting it to a string and then using string methods to convert it to your desired output, I believe a simpler approach is to use the Date object
function dateAdd(original, hours, minutes) {
const date = new Date(original);
date.setHours(original.getHours() + hours);
date.setMinutes(original.getMinutes() + minutes);
return date.toISOString();
}
When original = "2021-05-26T00:00:00.000Z" then the return value is "2021-05-26T10:20:00.000Z".
If you want a fixed time:
const date = new Date('2021-05-26T00:00:00.000Z');
date.setUTCHours(10);
date.setUTCMinutes(20);
date.setUTCSeconds(0);
date.setUTCMilliseconds(0);
// a cleaner approach:
date.setUTCHours(10, 20, 0); // hoursValue, minutesValue, secondsValue
console.log(date.toISOString());
Which produces the following:
"2021-05-26T10:20:00.000Z"
Another Solution
Your actual problem is being caused by the fact you call toString which returns a date string in the format of "Tue Aug 19 1975 23:15:30 GMT+0200 (CEST)" so when you're splitting by "T", that's way down at the end. toISOString will return the correct format.
Explanation
As you can see above, we avoid using string methods and use the methods that exist on Date. This approach is safer as you avoid issues with the difference between toISOString and toString. You may also find moment useful if you're using dynamic methods of changing dates regularly.
Note
In all honesty, I'm not entirely sure I understand the why behind what you're doing, so if I'm wrong please correct me so I can update my answer to be more relevant for you.
Learn More
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Why does new Date(year,month,day) not return an equivialent Date?

one day I fiddled with vanilla NodeJS using the node command line tool. (I am using node v13.11.0)
I tried to create a new Date at the 01.01.1970. I used the usual new Date(year, month, day) constructor.
As simple as it sounds, I entered new Date(1970, 1, 1) and found out, that it does not return 1970-01-01T00:00:00.0000Z. Instead, it returns 1970-01-31T12:00:00.000Z.
Has anyone an Idea, why this constructor does not return the equivalent date?
The constructor does more or less what you think:
x = new Date(1970,1,1)
1970-01-31T14:00:00.000Z
> x.getMonth()
1
> x.getDate()
1
> x.getHours()
0
(Note that months count from zero, so you requested the 1st of February).
But if you display the whole date as a string, it's showing the time in UTC, which might not be what you expect.

NPOI: Achieve Currency format as if formatted by Excel

I have seen some questions (like this one) here asking about if a cell in Excel can be formatted by NPOI/POI as if formatted by Excel. As most of you, I have to deal with issues with Currency and DateTime. Here let me ask how the formatting can be achieved as if it has been formatted by Excel? (I will answer this question myself as to demonstrate how to do it.)
Setting: Windows 10, English, Region: Taiwan
Excel format: XLSX (version 2007 and later)
(Sorry about various edit of this question as I have pressed the 'Enter' button at unexpected time.)
If you format a cell as Currency, you have 4 choices:
The internal format of each style is as follow:
-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00" numFmtId="164"/>
[RED]NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00;[Red]"NT$"#,##0.00" numFmtId="164"/>
-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00_);("NT$"#,##0.00)" numFmtId="7"/>
[RED]-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00_);[Red]("NT$"#,##0.00)" numFmtId="8"/>
Note: There is a pair of double quote (") comes before and after NT$.
(To get internal format of XLSX, just unzip it. The Style information is available in <unzip dir>\xl\Styles.xml Check out this answer if you need more information.)
(FYI: In formatCode, the '0' represent a digit. The '#' also represent a digit, but will not appear if the number is not large enough. So any number less than 1000 will not have the comma inside it. The '_' is a space holder. In format 3, '1.75' appears as 'NT$1.75 '. The last one is a space.)
(FYI: In numFmtId, for case 1 and case 2, number 164 is for user-defined. For case 3 and 4, number 7 and 8 are build-in style.)
For developers using POI/NPOI, you may find out if you format your currency column using Build In Format using 0x7 or 0x8, you can get only the third or fourth choice. You cannot get the first or second choice.
To get the first choice, you build upon style 0x7 "$#,##0.00);($#,##0.00)". You need to add the currency symbol and the pair of double quotes in front of it.
styleCurrency.DataFormat = workbook.CreateDataFormat().GetFormat("\"NT$\"#,##0.00");
Apply this format to a cell with number. Once you open the Excel result file, right click to check formatting, you will see the first choice.
Please feel free to comment on this post.
var cell5 = row.CreateCell(5, CellType.Numeric);
cell5.SetCellValue(item.OrderTotal);
var styleCurrency = workbook.CreateCellStyle();
styleCurrency.DataFormat= workbook.CreateDataFormat().GetFormat(string.Format("\"{0}\"#,##0.00", item.CurrencySymbol));//styleCurrency;
cell5.CellStyle = styleCurrency;
styleCurrency = null;
Iterate over loop for multiple currency.
Function to GetCurrencySymbol against currency Code on C#
private string GetCurencySymbol(string isOcurrencyCode)
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture)
.Select(culture =>
{
try
{
return new RegionInfo(culture.LCID);
}
catch
{
return null;
}
})
.Where(ri => ri != null && ri.ISOCurrencySymbol == isOcurrencyCode)
.Select(ri => ri.CurrencySymbol).FirstOrDefault();}

Manipulation of date in Groovy language

I have this script in Groovy:
currentDate = new Date().format( 'yyyyMMdd' )
I want to be able to manipulate the date in order to 'play' with the dates of it..
for example if I have this:20150701 I want to subtract days, weeks or months for example if I subtract one day it will be 20150630.
How can I do it without using TimeCategory?
thanks!
Without TimeCategory, you can only add or subtract days. If you want to add/subtract other fields, TimeCategory is a good way to go.
If your annoyance with TimeCategory is the with syntax, one alternative would be to use mixins (although they are generally considered deprecated since traits have been added to Groovy):
[Date, Integer].each { it.mixin(groovy.time.TimeCategory) }
def lastMonth = new Date() - 1.months
OK I have the answer to it, I tried this and it worked:
currentDate = new Date()
def yesterday = currentDate - 1
currentDate = yesterday.format("yyyyMMdd")

How to calculate exact year, month and day between two dates in vc++/MFC

In my application i have to find out exact year, month and day between two dates. I tried with below snip. but answer is not correct. I used CTime for from to to dates. The result is obtained in CTimeSpan class. CTimeSpan has member function such as GetDays. We shall find out year, month and day from Total Days, but answer is not correct. Is any way to do ?
Thanks in advance
There is no common function to do that.
My idea would be:
COleDateTime date1(1979,12,31,0,0,0),
date2(2004,10,01,0,0,0);
// Get the normal differences
int iYears = date2.GetYear()-date1.GetYear(),
iMonths = date2.GetMonth()-date1.GetMonth(),
iDays = date2.GetDay()-date1.GetDay();
// Problematic underflow of days.
if (iDays<0)
{
// One month less
--iMonths;
// Advance from the start date until we reach the 1st of next month
for (iDays=0; (date1+COleDateTimeSpan(iDays,0,0,0)).GetDay()!=1; ++iDays)
;
// Now get the days from the 1st of the second date to the desired date.
iDays += static_cast<int>((COleDateTime(date2.GetYear(),date2.GetMonth(),1,0,0,0)-date2).GetTotalDays());
}
// underflow of months
if (iMonths<0)
{
--iYears;
iMonths +=12;
}
I don't see any CTimeSpan::GetTotalDays() function in the MSDN Docs.
Anyway, the GetTotalHours / GetTotalMinutes functions return the number of Complete Hours/Minutes and does not fully represent the TimeSpan value; the best way would be to use GetTotalSeconds and convert it as necessary.

Resources