Grabbing parts of a date in a different timezone with moment - javascript

This may be an odd question, but I have a moment date which I will later need to grab parts of it for different usages. For example, I grab the day and display doing date.date() from moment.
All that is find and dandy, but the issue is timezones are relevant to this.
So I have my moment object, which is created from the string:
const properDate = moment.tz(date, 'YYYY-MM-DD hh:mm:ss.SSS', 'America/New_York')
From my understanding, for me to get the proper timezone time, I would do
properDate.format()
But this will convert it to a string. And I would like to be able to fetch the time and days on the correct timezone. So basically, when I do properDate.hours() I will get it in UTC's time, but I want it in America/New_York.
Say for example the date string I want to put in is 2018-12-31 02:00:00.000 +00:00
When I run it through the above code, and then do properDate.hours() I am going to get 2, but I would like to get it in the New York timezone, which would be 21, and would also be the previous day if I want to get the date.
I suppose a way around this would be to convert it to a date object using new Date and setting each one manually, perhaps? Something like this:
const dateWithTimezoneObject = new Date(properDate.year(), properDate.month(), properDate.date(), properDate.hours(), properDate.minutes())
But that sounds like a bit of a mess and I was wondering if there is a better way of getting this done, possibly through moment.
So, is there a way for me to get the parts of the moment object in the proper timezone time?

I believe what you're looking for is:
var m = moment("2018-12-31 02:00:00.000 +00:00","YYYY-MM-DD HH:mm:ss.SSS Z")
.tz('America/New_York');
m.hours() //=> 21
A few things:
Note the input format provided is case sensitive and needs to match the input string. In your question, you had hh instead of HH, and also didn't provide the Z for the time zone offset.
There are two different flavors of the tz function. moment.tz() is for constructing a moment where the input value is in terms of that time zone. moment().tz() is for converting a moment to a different time zone.
Though I just used moment in my example above, you could use moment.tz, moment.utc or moment.parseZone and the effect would be the same, but only because you included the offset +00:00 in the input string. If you don't actually have that offset, then you'd want to use moment.utc, like this:
var m = moment.utc("2018-12-31 02:00:00.000","YYYY-MM-DD HH:mm:ss.SSS")
.tz('America/New_York');
Regarding your proposed solution, that would be creating a Date object representing a different point in time. In general, once you are using Moment you should avoid using the Date object if you can use a Moment function instead.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
Test
<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>
<script>
const date = '2018-12-31 02:00:00.000 +00:00'
const new_york = moment(date,'YYYY-MM-DD HH:mm:ss.SSS Z')
.tz('America/New_York')
document.body.textContent =
`day: ${new_york.dates()} hour: ${new_york.hours()}`
</script>
</body>
</html>
https://momentjs.com/timezone/

Related

How to make Moment.js ignore the user's timezone?

I've got a form where I input an event that starts at a certain time. Let's say 9am.
To assign a date/time object I'm using MomentJs. The issue comes when displaying it in different time-zones.
In London will show up 9am as intended - in Kiev will show 11am.
How can I make MomentJS and the browser ignore which timezone is relevant for the user, and just displaying the time I'm giving?
Here's my code:
<p>
Start time:
{moment(event.startDate).format("HH:mm")}
</p>
Assuming you have stored the date as utc (which in this case you probably should have), you could use the following:
moment.utc(event.startDate).format("HH:mm")
Let me provide an alternative answer in Vanilla JavaScript. If you want to make it timezone 'neutral', you can first convert it to UTC using toISOString().
const current = new Date();
const utcCurrent = current.toISOString();
console.log(utcCurrent);
If you want to convert it to a specific timezone, such as London, you can use toLocaleString(). Do take note of the browser support for the timezone though.
const londonTime = new Date().toLocaleString('en-US', { timeZone: 'Europe/London' })
console.log(londonTime);
What you want is a normalized Datetime. This can get a little confusing since the concept of timezones is a rather arbitrary construct.
I like to think of Datetime values as "absolute" and "relative". An "absolute" Datetime is one that is true regardless of which timezone you're in. The most common example of these are UTC(+000) and UNIX Time (also known as Unix epoch, POSIX Time or Unix Timestampe).
UTC is pretty obvious. Its the current time at +000 timezone. UNIX time is a bit more interesting. It represents the number of seconds that have elapsed since January 1, 1970.
You should always store data, in both client and backend, as an "absolute" time. My preference is UNIX time since its represented as a single integer (nice and clean).
moment.js does this for you. When you instantiate your moment object, you can use:
var date = moment.utc(utcString)
or for Unix Time
var date = moment.unix(unixInt)
You can then use this object to display the date in any form you wish:
console.log(date.tz.("America/Toronto"))
The only way I could solve this is by removing the timezone and milliseconds info from the string. I used date-fns lib but I imagine moment will work the same way.
import { format } from 'date-fns'
const myDateTimeString = '2022-02-22T19:55:00.000+01:00'
const dateTimeWithoutTimezone = myDateTimeString.slice(0, 16) // <- 2022-02-22T19:55
format(new Date(dateTimeWithoutTimezone), 'HH:mm')

How to transform time from one timezone to another, ignoring local timezone?

I have a date formatted like this '2018/11/17 13:30', but unfortunately it is from another timezone. I know the initial timezone and target timezone, and wanna to transform date and time from one to another correctly. It looks like simple task, especially using moment library, but after reading docs I still didn't figure out how to do it right. Will be glad to any help, thanks.
You can use moment timezone to convert between two zones.
let date = "2018/11/17 13:30"
// make date-time local to LA
let d = moment.tz(date, "YYYY/MM/DD HH:mm", "America/Los_Angeles")
console.log("L.A", d.format('LT'))
// convert to Chicago
console.log("Chicago:", d.tz("America/Chicago").format('LT'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

Foreign Time to Local Time

I'm trying to convert foreign time to Local Time. I'm getting a date and time in Europe/London. Currently I'm using moment-timezone to get my code working, however its giving me a wrong output.
resultDate = new moment('2017-06-30T22:10:00').tz('Europe/London').format('YYYY-MM-DD HH:mm:ss');
I think the code thinks that the date input is already in local time where I need to convert it into Europe/London which would give a local result, where as what I want is to actually convert the foreign time to local time.
In short the date and time as my input (2017-06-30T22:00:00), I am expecting it to be 7 hours in advance (2017-07-1T05:00:00) since I currently live in Asia/Manila, 7 hours in advance to London. However I'm getting 2017/06/30 15:00:00 +0100 as my result.
Is there a way for me to do this by utilizing the information 'Europe/London' or 'Asia/Manila' as seen in my code?
You can use moment.tz to parse your input as Europe/London time and then use the tz function to convert it to Asia/Manila.
The first parses your input using the given timezone while the latter convert a moment objet to a given timezone.
Here a working sample:
// Parse input considering as London tz
var timeInLondon = moment.tz('2017-06-30T22:10:00', 'Europe/London');
// Converting input to Manila
var timeInManila = timeInLondon.tz('Asia/Manila');
// Show result
console.log(timeInManila.format('YYYY-MM-DD HH:mm:ss'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data-2010-2020.min.js"></script>

Convert hour to date time without adding +1

Hi im using moment js to convert this string 20:00 I tried:
var a = moment("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00+01:00
the problem when I store in mongodb it become
2016-09-10T19:00:00.000Z
I want to store 2016-09-10T20:00:00.000Z
anyway can explain why please ?
When you say that you want to store 2016-09-10T20:00:00.000Z what you are saying is that you want to assume that your date and time is UTC.
To assume that the date you are parsing is a UTC value, use moment.utc
var a = moment.utc("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00Z
Note that when you parse a time without a date, moment assumes the current date. This may not be the behavior that you want.
I'm also not sure if you want a UTC date (which is what you are saying), or a local date without an offset indicator. If you want a local date without an offset indicator, simply use a format without an offset:
moment.utc("20:00", "HH:mm").format('YYYY-MM-DDTHH:mm:ss.SSS')
"2016-09-08T20:00:00.000"
If you are dealing with local dates that do not have a time zone association, I recommend using moment.utc to parse, as this will ensure that the time does not get shifted to account for DST in the current time zone.
For more information about how to parse dates into the time zone or offset that you would like in moment, see my blog post on the subject.
This it how it should look:
var a = moment("20:00", "HH:mm")
console.log(a.utcOffset('+0000').format())
<script src="http://momentjs.com/downloads/moment.min.js"></script>
Doe, the problem is that you are using timezones when you create the date.
MomentJS uses your current timezone automatically.
Mongo however saves the time as it would be in another timezone.
Therefore, if you want the two strings to format the same way, you need to set the timezone.

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