Wrong date format with toLocaleString on server side - node.js

Using this on a server side (a Firebase function, nodejs )
var d=new Date();
var date = d.toLocaleString('default', { month: 'long'}) + ", " + d.getFullYear();
I am expecting to get March, 2020 , since this is what i get on the JS client side, but instead when run on the server side i get - M03, 2020 .

I tried the following code:
const date = require('date-and-time');
var d = new Date();
var myDate = d.toLocaleString('default', { month: 'long'}) + ", " + d.getFullYear();
console.log(myDate);
Output:
March, 2020
Now, if you are trying to store a Javascript Date object into Firebase, this object will be stored as a Timestamp object. I think this would explain the reason why you are noticing some discrepancies in the format.
Optionally, you can convert the Date object to String and store it in Firebase as such. This is more human-readable than ISO 8601 and Timestamp - 0001-01-01T00:00:00Z
You can read more about this in the following documentation about Timestamp and Data types. Moreover, there exists a Timestamp built-in method toDate() that returns a new Date corresponding to a certain timestamp, if conversion is needed.

Related

Convert user define time to UTC using moment

We have application where we ask user to define time when they want to publish some content. In our application, user will select that content should publish X(0-5) day before target date and y time (0-23).
So if user create a content with publish date = "09/21/2021" and publish time as 3 it means this content needs to publish at 3 AM on 09/21/2021.
In our Mongo DB we need to store the calculated date as "2021-09-21T07:00:00" So it can be pulled by our Cron Job.
We tried will following without any success
var promotedDate = "2021-08-19 04:00:00"
var fmt = "YYYY-MM-DD hh:mm:ss";
var m = moment.utc(promotedDate, fmt);
console.log('promoted date ', tempDate)
console.log(m.local().format(fmt));
console.log(m.utc().format(fmt));
But it gives 2021-08-19 12:00:00
Any help ?
You can use moment.toISOString(). That will give you UTC regardless of the timezone of the moment in question thus: 2013-02-04T22:44:30.652Z.
Since that comes with milliseconds and a Z for Zulu time, we need to strip off the last 5 characters with string.slice():
const promotedDate = "2021-08-19 04:00:00";
const m = moment.utc(promotedDate, "YYYY-MM-DD hh:mm:ss");
const iso8601 = m.toISOString()
.slice(0,-5); // removes milliseconds and `Z` for Zulu
console.log( `promoted: ${promotedDate}` );
console.log( `iso8601: ${iso8601} );

Reactjs Timezone convertion

I am connected mssql database and get some informations includes Date_Time.
Time is coming like 2021-01-30T15:08:25.357Z. I want to convert it to dd-mm-yy hh:mm:ss format.
So, it should be 30-01-2021 15:08:25.
I used this method but it is not exactly that I want.
var d1 = new Date(datey).toLocaleDateString("tr")
var newTime=d1+" "+
new Date(datey).getUTCHours()+":"+
new Date(datey).getUTCMinutes()+":"+
new Date(datey).getUTCSeconds()
// it returns 30/01/2021 15:8:25
Maybe, In there, I want to see time fomat with 0 such as 15:08. When hour 2 a.m it just 2:0 but I want to see it 02:00.
How should I do , is there any idea?
I would suggest using a date/time library such as moment.js, this will make date manipulation much easier, parsing and formatting your date is then very simple:
const input= "2021-01-30T15:08:25.357Z";
console.log("Input date:", input);
// To convert the date to local before displaying, we can use moment().format()
const formattedDateLocal = moment(input).format("DD-MM-YY HH:mm:ss");
console.log("Formatted date (Local Time):", formattedDateLocal );
// To display the UTC date, we can use moment.utc().format()
const formattedDateUTC = moment.utc(input).format("DD-MM-YY HH:mm:ss");
console.log("Formatted date (UTC):", formattedDateUTC );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

Converting Excel date to Moment date gives a wrong year output

I am working on importing data in an Excel file and it has date column.
In my app, that date column value comes as a serial number like 43101.622083333335 which stands for 01/01/2018.
When converting this serial number from Excel back to the normal date it stands for, it gives wrong year.
For example, it gives 01-Jan-1970 instead of 01-Jan-2018
``
var moment = require('moment');
var excelDate = 43101.622083333335;
var date = moment(new Date(excelDate));
var dateWithNewFormat = date.format('DD-MMM-YYYY');
console.log(dateWithNewFormat);
``
Output: 01-Jan-1970 instead of 01-Jan-2018
Any help ?
Thanks in advance.
I don't think this is an issue with the moment library. It seems that you aren't calling Date with a valid constructor argument with new Date(excelDate) (see official documentation for Date here).
The Date class doesn't understand the concept of 'Excel time' but it does understand the concept of a unix timestamp. If you refer to this post, you can see how to convert from Excel time to a unix timestamp, depending on which version of Excel you are using.
Then, I would change your code to:
var moment = require('moment');
var excelDate = 43101.622083333335;
var unixTimestamp = (excelDate-25569)*86400 //as per the post above, convert Excel date to unix timestamp, assuming Mac/Windows Excel 2011 onwards
var date = moment(new Date(unixTimestamp)); //Pass in unix timestamp instead of Excel date
var dateWithNewFormat = date.format('DD-MMM-YYYY');
console.log(dateWithNewFormat);

How to set timezone with moment?

i am using moment for getting server time .
moment.tz.setDefault("Asia/Kolkata");
var now = new Date();
var _p_date = moment.tz(now, zone).format();
time when inserting _p_date = 2016-01-05T18:32:00+05:30
But in database date variable is type of DATETIME. and time is saved as 2016-01-05 18:32:00.
and after that when i comparing with this to get time_ago funcionality. providing me wrong estimation.
using time ago = moment("2016-01-05T18:32:00.000Z").fromNow(); // is showing In 5 hours
Since your initial timezone is lost you have to create moment.tz object with selected timezone. Try this plunker
var date = moment.tz(moment("2016-01-05T18:32:00.000Z", "YYYY-MM-DDTHH:mm")
.format('YYYY-MM-DD HH:mm'), 'Asia/Kolkata');
console.log(date.fromNow());

MomentJS getting JavaScript Date in UTC

I am not able to get the JavaScript Date string for MongoDB record via the following. It keeps using my local time.
var utc = moment.utc().valueOf();
console.log(moment.utc(utc).toDate());
Output:
Tue Nov 11 2014 14:42:51 GMT-0500 (EST)
I need it to be in UTC, so I can stick this timestamp in Mongo so type would be Date.
How can I do that?
A timestamp is a point in time. Typically this can be represented by a number of milliseconds past an epoc (the Unix Epoc of Jan 1 1970 12AM UTC). The format of that point in time depends on the time zone. While it is the same point in time, the "hours value" is not the same among time zones and one must take into account the offset from the UTC.
Here's some code to illustrate. A point is time is captured in three different ways.
var moment = require( 'moment' );
var localDate = new Date();
var localMoment = moment();
var utcMoment = moment.utc();
var utcDate = new Date( utcMoment.format() );
//These are all the same
console.log( 'localData unix = ' + localDate.valueOf() );
console.log( 'localMoment unix = ' + localMoment.valueOf() );
console.log( 'utcMoment unix = ' + utcMoment.valueOf() );
//These formats are different
console.log( 'localDate = ' + localDate );
console.log( 'localMoment string = ' + localMoment.format() );
console.log( 'utcMoment string = ' + utcMoment.format() );
console.log( 'utcDate = ' + utcDate );
//One to show conversion
console.log( 'localDate as UTC format = ' + moment.utc( localDate ).format() );
console.log( 'localDate as UTC unix = ' + moment.utc( localDate ).valueOf() );
Which outputs this:
localData unix = 1415806206570
localMoment unix = 1415806206570
utcMoment unix = 1415806206570
localDate = Wed Nov 12 2014 10:30:06 GMT-0500 (EST)
localMoment string = 2014-11-12T10:30:06-05:00
utcMoment string = 2014-11-12T15:30:06+00:00
utcDate = Wed Nov 12 2014 10:30:06 GMT-0500 (EST)
localDate as UTC format = 2014-11-12T15:30:06+00:00
localDate as UTC unix = 1415806206570
In terms of milliseconds, each are the same. It is the exact same point in time (though in some runs, the later millisecond is one higher).
As far as format, each can be represented in a particular timezone. And the formatting of that timezone'd string looks different, for the exact same point in time!
Are you going to compare these time values? Just convert to milliseconds. One value of milliseconds is always less than, equal to or greater than another millisecond value.
Do you want to compare specific 'hour' or 'day' values and worried they "came from" different timezones? Convert to UTC first using moment.utc( existingDate ), and then do operations. Examples of those conversions, when coming out of the DB, are the last console.log calls in the example.
Calling toDate will create a copy (the documentation is down-right wrong about it not being a copy), of the underlying JS Date object. JS Date object is stored in UTC and will always print to eastern time. Without getting into whether .utc() modifies the underlying object that moment wraps use the code below.
You don't need moment for this.
new Date().getTime()
This works, because JS Date at its core is in UTC from the Unix Epoch. It's extraordinarily confusing and I believe a big flaw in the interface to mix local and UTC times like this with no descriptions in the methods.
This will give you the UTC timezone DateTime.
var convertedUtcDateTime = moment.utc(dateTimeToBeConverted);
When you call .utc(), all you're doing is setting a flag in the Moment object that says "this must format as UTC." You can see this change if you inspect the object's properties.
As another answer mentioned, the point in time remains the same. This ensures calculations etc. can be carried out without worrying about the time zone.
A JavaScript Date also stores timezone information, and similarly will format the value it represents as local or UTC depending on what method you call.
Option 1
Use the formatting methods as they were intended, and make the last thing you do before sending the value to the server a format into a UTC string.
For Moment, that's simply calling .toISOString() on any date local or otherwise, or the .format() method after calling .utc() if you want to specify a different format.
For JS dates, that's also a .toISOString() method.
If for some reason you don't have the ability to keep the dates in local time, or can't transform to a string for the data send, you have (at least) two further options:
Option 2
Use the JS Date constructor to manually create a datetime in the local timezone, pulling the components from your UTC Moment object.
let utc = moment().utc();
let date = new Date(utc.year(), utc.month(), utc.date(), utc.hour(), utc.minute(), utc.second(), utc.millisecond());
Alternatively, get the current datetime and then set the hours and minutes as appropriate for the timezone change.
You'll end up with a date representation of the UTC time marked as local time. This is not the correct time, as you're now offset by the time zone, but it might solve a problem in a pinch.
Option 3
Similar to option 2, this is another way to create an offset Date where UTC is marked as the local time zone.
Export the ISO string from either Moment or JS, strip off the Zulu flag at the end, and use the string constructor for Date to pull it back in.
new Date(new Date().toISOString().slice(0,-1));
Again, this is not actually the correct time and calculations against other datetimes may be incorrect. Your best option is still to send up a UTC ISO string to the server when you can.
Or simply:
Date.now
From MDN documentation:
The Date.now() method returns the number of milliseconds elapsed since January 1, 1970
Available since ECMAScript 5.1
It's the same as was mentioned above (new Date().getTime()), but more shortcutted version.

Resources