nodejs convert timestamp string into date with custom timezone and to UTC - javascript

Suppose i get the value '2014-03-03 16:20:20' as an input, I'd like to convert it
to it's real time with timezone (i.e, node sits in Europe , but timestamp was collected in America), and after that I'd like to get the UTC representation of the real value.
Any idea what packages can help? Tried moment.js with no luck..

finally found the answer with momentjs-timezone ,
which is kinda funny since you wont get a event a hint about on the mainsite http://momentjs.com/timezone/ but you can find it on http://github.com/moment/moment-timezone
anyhow here's how you do it :
var tz0 = moment.tz("2014-03-03 16:20:20", "Asia/Jerusalem")
var tz1 = moment.utc(tz0);
console.log(tz0.format('YYYY-MM-DD hh:mm:ss'));
console.log(tz1.format('YYYY-MM-DD hh:mm:ss'));
and the output as you can see respectivly
2014-03-03 04:20:20
2014-03-03 02:20:20

// moment.js
var utc = moment('2014-03-03 16:20:20','YYYY-MM-DD HH:mm:ss', 'us');
// or timezone string pass from client
var eu = utc.zone("+02:00");
var eu = utc.zone("-02:00");

momentjs may help you. Like the following:
Could you format the input with ISO date plus timezone info, like 2014-03-03T16:20:20-05:00 (supposing you get from local time at GMT-5 timezone)
Then call: moment.parseZone('2014-03-03T16:20:20-05:00').zone(1).format() (supposing you want to get local time at GMT+1 timezone)
Hope that help,
Ron

Timezone is an elegant module for this.
var tz = require("timezone/loaded");
var formattedDate = tz(unformattedTimestamp, '%d %B %Y, %-I:%M %p', "Europe/Amsterdam");
You can use bootstraphelper to capture user's timezone.

Related

Why does ISO date in Mongodb display one day earlier?

The stored date looks like this:
...
"date_of_birth" : ISODate("1920-01-02T00:00:00Z"),
...
Using moment, it is formatted in the model (in order to populate the input for updating the document) like this:
AuthorSchema
.virtual('date_of_birth_update_format')
.get(function(){
// format in JavaScript date format (YYYY-MM-DD) to display in input type="date"
return this.date_of_birth ? moment(this.date_of_birth).format('YYYY-MM-DD') : '';
});
Retrieved from the collection and displayed, it displays as one day earlier like this:
01/01/1920
I would appreciate any help to resolve this.
The date from mongo is always in GMT, and your server might be in other timezone. You need to convert date to GMT before formatting.
var moment = require("moment-timezone")
AuthorSchema.virtual('date_of_birth_update_format').get(function(){
return this.date_of_birth ? moment(this.date_of_birth).tz('GMT').format('YYYY-MM-DD') : '';
});
The Z in the ISO 8601 format implies 'GMT' i.e. 1920-01-02T00:00:00+0000. Moment will take your timezone into consideration. If you are in the continental US, your time zone offset is -0400—-0800.
1920-01-02T00:00:00Z = 1920-01-01T6:00:00-0600 In Pacific Standard Time for example.
It depends on the time zone which you are in for example am in India so GMT for me is +5:30 so whenever I retrieve from db I would add up 5:30 to time so that it matches the date and to answer why it storing it a day before because it stores date in ISO format that's why
Same problem here. I was using EJS to show the date retrieved from the MongoDB database. I'm not sure if the problem is with EJS, but I solved it like this:
All I had to do was to set the timeZone to GMT in the front-end:
date.toLocaleString("pt-BR", {timeZone:"GMT", day: "numeric", month: "numeric", year:"numeric"});

moment-timezones.js, how to convert date in spesific timezone to utc, disregarding my local timezone?

my system uses timezone UTC+03:00 ,
im trying to get a date in string format, represented by NY timezone,
and convert it to a Date object in utc
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York")
.tz("Z").toDate();
doesnt work correctly
how am i even suppose to convert to utc time?
-----------edit---------------
i got it to work, using the timezone "Africa/Accra" , where UTC offset is 0, and ther is no daylight savings time:
moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York").tz("Africa/Accra")
but this solution is a bad workaround, and if the government of Accra decide to change the time laws, will stop working!
is there a way to set the utc offset to 0 in momentjs-timezones?
As Álvaro González mentioned, that Date object does not contain Time zone information.
I do the following:
new Date(moment.tz(date, currentTimezone).tz(newTimezone).format('YYYY/MM/DD HH:mm:ss'))
where date is a date object or a string (e.g. '2017-10-30 16:30:00.0000')
so, I change date from currentTimezone to newTimezone and after that new Date object will be returned
Let's change '2017-10-30 16:30:00.0000' from UTC to America/Toronto (UTC-4)
new Date(moment.tz(date, 'UTC').tz('America/Toronto').format('YYYY/MM/DD HH:mm:ss'))
And I got
Mon Oct 30 2017 12:30:00 GMT+0400
GMT+0400 is my timezone and console.log() just shows it with any
date object and it can mislead you. Please, don't look at the this
timezone.
Let's change '2017-10-30 16:30:00.0000' from Europe/Samara (UTC+4) to America/Toronto (UTC-4)
new Date(moment.tz('2017-10-30 16:30:00.0000', 'Europe/Samara').tz('America/Toronto').format('YYYY/MM/DD HH:mm:ss'))
Firstly, moment.tz undertands that date has no timezone information and associate with Europe/Samara (UTC+4)
timezone. After that computes difference between new and old
timezone (it's -8 hours in this case)
And returns result
Mon Oct 30 2017 08:30:00 GMT+0400
And answer on your question
If xsltDate is a date object or string which do not contain timezone information
dateUTC = new Date(moment.tz(xlsxDate, "America/New_York").tz("UTC").format('YYYY/MM/DD HH:mm:ss'));
If xsltDate contain timezone information (e.g.'2013-06-01T00:00:00-04:00'), then no need to tell moment.tz which timezone xlsxDate has, just mention a new timezone
dateUTC = new Date(moment.tz(xlsxDate, "UTC").format('YYYY/MM/DD HH:mm:ss'));
Short answer is that you cannot.
The .toDate() method of the Moment library returns a native Date object. Such objects do not keep memory of any specific time zone (that's one of the reasons to use Moment in the first place), they just keep track of the exact time moment represented and merely pick a time zone when formatting to string, which is either UTC or the browser's time zone (not an arbitrary one).
The long answer is that you're probably getting correct results but are printing them with a method that uses the browser's time zone.
i found a function that does what i was trying to do, it belongs to the momentjs library itself: utcOffset(n) sets the offset to n.
(i also had to explicitly write the date string format correctly, thanks VincenzoC)
this is the code i was trying to write:
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York");
const dateUTC = dateInNY.utcOffset(0).toDate();
however, the toDate function changes the timezone to my local timezone anyway, so .utcOffset(0) is redundat, and i can just use moment this way:
const dateInNY = moment.tz(xlsxDate, "M/D/YYYY h:mm a", "America/New_York");
const dateUTC = dateInNY.toDate();
and change the Date objects date to utc time later (in my case, the JSON.stringify stuff i use later does that for me)

Convert utc date to local date using momentjs

I have a DateTime string like 2/24/2017 17:00:00 which comes from a web service. The time is UTC time. Now i want to convert it to user's local time and display it in browser. And i'm using Moment.js.
I've tried:
var utcTime= moment('2/24/2017 17:00:00' + " +0000", "MM/DD/YYYY HH:mm:ss Z");
var localTime = utcTime.add(new Date().getTimezoneOffset().toString(), 'm').toDate();
It will work but somehow looks strange. Am i missing something? Is there a better way to do this?
Write it like this:
moment.utc('2/24/2017 17:00:00', "MM/DD/YYYY HH:mm:ss").local().format('lll');
Reference: http://momentjs.com/

Return date and time in ("YYYY-MM-DD HH:mm") format when using moment.js (timezone)

I am using moment-timezone so I can convert from selected timezone to timezone of a client.
I wasn't able to implement it in a better way than this:
convertSelectedTimeZoneToClients() {
let timeZoneInfo = {
usersTimeZone: this.$rootScope.mtz.tz.guess(),
utcOffset: this.formData.timeZone.offset,
selectedDateTime: this.toJSONLocal(this.formData.sessionDate) + " " + this.formData.sessionTime
};
let utcTime = this.$rootScope.mtz.utc(timeZoneInfo.selectedDateTime).utcOffset(timeZoneInfo.utcOffset).format("YYYY-MM-DD HH:mm");
let convertedTime = this.$rootScope.mtz.tz(utcTime, timeZoneInfo.usersTimeZone).format("Z");
return convertedTime;
}
So basically I am using usersTimeZone: this.$rootScope.mtz.tz.guess(), guess() function to find out timezone from the browser.
Then I get values from datetime picker and dropdown and convert them to UTC value by using utcOffset.
At the end I want to convert that utc value to user timezone value.
I get object like this:
_d represent correct value after conversion. I have tried adding bunch of different .format() paterns on convertedTime variable, but I am not able to retrive time in this format: "YYYY-MM-DD HH:mm". I guess it works differentlly than when using .utcOffset() function.
Can anybody help me with this?
You don't need to guess the client time zone to convert to local time. Just use the local function.
For example:
moment.tz('2016-01-01 00:00', 'America/New_York').local().format('YYYY-MM-DD HH:mm')
For users located in the Pacific time zone, this converts from Eastern to Pacific and you get an output string of "2015-12-31 21:00". For users in other time zones, the output would be different, as expected.
You don't need to format to a string and re-parse it, or manually manipulate the UTC offset either. That is almost never warranted.

Moment.js transform to date object

Using Moment.js I can't transform a correct moment object to a date object with timezones. I can't get the correct date.
Example:
var oldDate = new Date(),
momentObj = moment(oldDate).tz("MST7MDT"),
newDate = momentObj.toDate();
console.log("start date " + oldDate)
console.log("Format from moment with offset " + momentObj.format())
console.log("Format from moment without offset " + momentObj.utc().format())
console.log("(Date object) Time with offset " + newDate)
console.log("(Date object) Time without offset "+ moment.utc(newDate).toDate())
Use this to transform a moment object into a date object:
From http://momentjs.com/docs/#/displaying/as-javascript-date/
moment().toDate();
Yields:
Tue Nov 04 2014 14:04:01 GMT-0600 (CST)
As long as you have initialized moment-timezone with the data for the zones you want, your code works as expected.
You are correctly converting the moment to the time zone, which is reflected in the second line of output from momentObj.format().
Switching to UTC doesn't just drop the offset, it changes back to the UTC time zone. If you're going to do that, you don't need the original .tz() call at all. You could just do moment.utc().
Perhaps you are just trying to change the output format string? If so, just specify the parameters you want to the format method:
momentObj.format("YYYY-MM-DD HH:mm:ss")
Regarding the last to lines of your code - when you go back to a Date object using toDate(), you are giving up the behavior of moment.js and going back to JavaScript's behavior. A JavaScript Date object will always be printed in the local time zone of the computer it's running on. There's nothing moment.js can do about that.
A couple of other little things:
While the moment constructor can take a Date, it is usually best to not use one. For "now", don't use moment(new Date()). Instead, just use moment(). Both will work but it's unnecessarily redundant. If you are parsing from a string, pass that string directly into moment. Don't try to parse it to a Date first. You will find moment's parser to be much more reliable.
Time Zones like MST7MDT are there for backwards compatibility reasons. They stem from POSIX style time zones, and only a few of them are in the TZDB data. Unless absolutely necessary, you should use a key such as America/Denver.
.toDate did not really work for me, So, Here is what i did :
futureStartAtDate = new Date(moment().locale("en").add(1, 'd').format("MMM DD, YYYY HH:MM"))
hope this helps
Since momentjs has no control over javascript date object I found a work around to this.
const currentTime = new Date();
const convertTime = moment(currentTime).tz(timezone).format("YYYY-MM-DD HH:mm:ss");
const convertTimeObject = new Date(convertTime);
This will give you a javascript date object with the converted time
The question is a little obscure. I ll do my best to explain this. First you should understand how to use moment-timezone. According to this answer here TypeError: moment().tz is not a function, you have to import moment from moment-timezone instead of the default moment (ofcourse you will have to npm install moment-timezone first!). For the sake of clarity,
const moment=require('moment-timezone')//import from moment-timezone
Now in order to use the timezone feature, use moment.tz("date_string/moment()","time_zone") (visit https://momentjs.com/timezone/ for more details). This function will return a moment object with a particular time zone. For the sake of clarity,
var newYork= moment.tz("2014-06-01 12:00", "America/New_York");/*this code will consider NewYork as the timezone.*/
Now when you try to convert newYork (the moment object) with moment's toDate() (ISO 8601 format conversion) you will get the time of Greenwich,UK. For more details, go through this article https://www.nhc.noaa.gov/aboututc.shtml, about UTC. However if you just want your local time in this format (New York time, according to this example), just add the method .utc(true) ,with the arg true, to your moment object. For the sake of clarity,
newYork.toDate()//will give you the Greenwich ,UK, time.
newYork.utc(true).toDate()//will give you the local time. according to the moment.tz method arg we specified above, it is 12:00.you can ofcourse change this by using moment()
In short, moment.tz considers the time zone you specify and compares your local time with the time in Greenwich to give you a result. I hope this was useful.
To convert any date, for example utc:
moment( moment().utc().format( "YYYY-MM-DD HH:mm:ss" )).toDate()
let dateVar = moment('any date value');
let newDateVar = dateVar.utc().format();
nice and clean!!!!
I needed to have timezone information in my date string. I was originally using moment.tz(dateStr, 'America/New_York').toString(); but then I started getting errors about feeding that string back into moment.
I tried the moment.tz(dateStr, 'America/New_York').toDate(); but then I lost timezone information which I needed.
The only solution that returned a usable date string with timezone that could be fed back into moment was moment.tz(dateStr, 'America/New_York').format();
try (without format step)
new Date(moment())
var d = moment.tz("2019-04-15 12:00", "America/New_York");
console.log( new Date(d) );
console.log( new Date(moment()) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>
moment has updated the js lib as of 06/2018.
var newYork = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
newYork.format(); // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format(); // 2014-06-01T17:00:00+01:00
if you have freedom to use Angular5+, then better use datePipe feature there than the timezone function here. I have to use moment.js because my project limits to Angular2 only.
new Date(moment()) - could give error while exporting the data column in excel
use
moment.toDate() - doesn't give error or make exported file corrupt

Categories

Resources