Initialize a Moment with the timezone offset that I created it with - javascript

I'm using moment and moment-timezone in javascript, and this part of it is one of the most unintuitive API's I've ever seen.
I would expect that:
moment("2015-12-14T04:00:00Z").utcOffset()
would be a pure function and return the offset included in the argument, which is 0. But instead it implicitly converts it to my local timezone offset (PST), so this returns -480 Why?? I asked what offset the object i just created has, not what offset I'm currently in. It would be like if I wrote an api where calling User.find(123).name() returns your name instead of the name of user 123.
Anyway, I can do
moment("2015-12-14T04:00:00Z").tz("utc").utcOffset()
But my datetime string is dynamic, so I don't know the timezone.
How can I get the behavior I expected, a Moment in js that is in the timezone offset included in the string i passed in?

Use parseZone to keep the offset as it was passed in.
moment.parseZone("2015-12-14T04:00:00Z")
As to the "why?" part of your question:
moment(...) is local mode. Ambiguous input (without offset) is assumed to be local time. Unambiguous input (with offset) is adjusted to local time.
moment.utc(...) is utc mode. Ambiguous input is assumed to be UTC. Unambiguous input is adjusted to UTC.
moment.parseZone() keep the input zone passed in. If the input is ambiguous, it is the same as local mode.
moment.tz(...) with the moment-timezone plugin can parse input in a specific time zone.
Keep in mind that moment has to contend with a wide variety of inputs.
Also keep in mind that a time zone and a time zone offset are two different things. An offset of -08:00 doesn't necessarily mean you are in the US Pacific time zone.

Related

How do I get the result of javascript new Date().getTimezoneOffset() transferred to C# backend?

See the title: for the solution I'm working on, I need to get the current timezone offset (from the client, running javascript/jQuery) and use it in backend C# code.
The question is rather similar to the one asked here, but there are a few differences - the main one being that I am pretty sure that the time on the client computer won't be tampered with. So new Date().getTimezoneOffset() will do just fine.
I cannot read the value upon submitting a form since the user is not working in a form: after the user has logged in, among the items that are visible on the screen is a table with data entered by the user or by other users. This data contains UTC datetimes that have to be adjusted according to the client's timezone. C# code is responsible for retrieving and formatting the data - hence my question.
What would suffice, is storing the value somewhere so that C# can read it when necessary. But I don't think that can be done as well. What would be the approach here?
Thanks in advance!
Your suggested approach is flawed in that the current offset from the client's browser is only going to apply to the current date and time. In reality, time zone offsets change over time within a given time zone. You cannot just take a singular offset from one point in time and expect to use it to convert other dates and times to the same time zone. Instead, you need to use the string that identifies the time zone, not an offset from that zone.
As an example, consider the Eastern time zone in the United States. For part of the year, it uses UTC-5, and we call it Eastern Standard Time (EST). In another other part of the year, it uses UTC-4, and we call it Eastern Daylight Time (EDT). This time zone is identified by either the IANA time zone ID "America/New_York", or the Windows time zone ID "Eastern Standard Time" (which covers the entire zone, both EST and EDT despite its wording).
So, break this problem apart into a few steps:
In JavaScript, identify the users's IANA time zone (America/New_York):
If you are targeting modern web browsers, you can call this function:
Intl.DateTimeFormat().resolvedOptions().timeZone
If you need to support older web browsers, you can use jsTimeZoneDetect, or moment.tz.guess() from Moment-Timezone.
Send that string to your web server through whatever mechinsm you like (form post, XHR, fetch, etc.)
In your .NET code, receive that string and use it to reference the time zone and do the conversion. You have two options:
You can use Noda Time, passing the IANA time zone ID to DateTimeZoneProviders.Tzdb as shown in the example on the home page.
You can use .NET's built-in TimeZoneInfo object. If you're running .NET Core on non-Windows systems (Linux, OSX, etc.) you can just pass the IANA time zone ID to TimeZoneInfo.FindSystemTimeZoneById. If you are on Windows, you'll need to first convert it to a Windows time zone ID ("Eastern Standard Time"). You can use TZConvert.GetTimeZoneInfo from my TimeZoneConverter library.
Once you have either a DateTimeZone from Noda Time, or a TimeZoneInfo object, you can use the methods on it to convert UTC values to local time values for that time zone. Each of these will apply the correct offset for the point in time being converted.
I'll also say, many applications simply ask the user to choose their time zone from a dropdown list and save it in a user profile. As long as you're storing a time zone identifier string and not just a numeric offset, this approach is perfectly acceptable to replace steps 1 and 2 above.

Forcing Date() constructor argument time zone interpretation

I have an use case where I use input from the user, which is on the form YYYY-MM-DD'T'TT:mm to create a Date object in Javascript. The problem is that Firefox and Chrome interpret the input as the local time (which is what I want), whilst Safari interprets the input as UTC time and converts it to local. How do I force Safari to use the same interpretation of the input as the other two?
The simplest way is to parse the string yourself (it's trivial, after all) and use the multiple-argument Date constructor, which always works in local time. Or use a library like Moment.js to do it for you. I was tempted to suggest adding a timezone offset (+0400, etc.) to the string (based on getTimezoneOffset on a Date object), but determining the right timezone offset requires that you know the date/time (because of Daylight Savings Time), and so...you'd have to do the work anyway.

JavaScript - formatting date with current timezone

I am using the moment.js library. I have dates in this format: "2014-06-19T18:00:00+02:00" (string). I want to display the date formatted with the user's timezone.
moment.js docs specifies to use moment("2014-06-19T18:00:00+02:00").utc().format()
My questions are:
How can I set the timezone once and not have to put .utc() every time?
How can I test the timezone functionality? Should I change my computer's clock?
Calling .utc() would actually translate the value you put in to UTC. If you want the user's local time zone, then you should just omit that and call .format().
That you passed a +02:00 offset with the original value doesn't matter. By default, moment will adjust the value to the user's time zone.
On the other hand, if you want to keep the offset you provided, regardless of the user's time zone, then you can use the parseZone function.

Convert timestamp with specified offset for timezone with Date();

I've been digging through as many things as I can find, and I can't seem to find what it is I am looking for, so I am coming to the conclusion that I either don't know what I am looking for or its not possible. Either way..
What I am trying to achieve is taking a timestamp example: 1373439600000 and a given offset of -12 to 12 (is that correct, as far as range goes?) so I can then take that timestamp above subtract from it accordingly, and pass that new timestamp to the Date() function so I can then manipulate it for human readable display.
The offset is two part, It is user specified in one instance while in the other it is going to default to the local getTimezoneOffset() if not specified. So trying to figure out how to take that range and work with that. To do everything accordingly.
Ideas? Am I even approaching this in a correct manor?
The timestamps I am working with are already UTC, not sure of that makes a difference.
The JavaScript Date type has many problems, but one of its major quirks is that it only understands two time zones - UTC, or Local. It uses UTC internally and in certain properties and functions like .toUTCString(), but otherwise it uses the local time zone.
Many browsers will accept an offset when parsing a Date from a string, but that will just be used to set the UTC time. Anything on the way out will be converted back to the local time zone again.
Fortunately, there are some great libraries out there for working around these problems. Moment.js is perfectly suited for this. Here is an example of what you might be looking for:
moment(1373439600000).zone(8).format("YYYY-MM-DD HH:mm:ss Z")
// output: "2013-07-09 23:00:00 -08:00"
Of course, you can format as needed, or pass in a more complex zone offset like "+05:30". And if you need to use an actual IANA time zone, there is the moment-timezone companion project, which you could do something like this:
moment(1373439600000).tz('America/New_York').format("YYYY-MM-DD HH:mm:ss Z")
// output: "2013-07-10 03:00:00 -04:00"
Unfortunately the Date object does not provide may facilities for working with timezones. If you have the offset though, you should be able to compute the offset in milliseconds. Then you can add (subtract?) that value to your timestamp and use it to construct the appropriate Date.
Does that help?

moment.utc('date string').format('DD-MMM-YYYY') returns the previous date

The Date in my database is getting stored as: '31-MAR-20'. I am using the following code to display the date back on UI.
moment.utc(data['dateString']).format('DD-MMM-YYYY');
But the above code is displaying the previous date i.e. 30-Mar-2020. How do I correct this issue ? Can I do it without using moment.js.
Thanks
You could attempt to use the default moment() for local mode.
From those docs:
moment(...) is local mode. Ambiguous input (without offset) is assumed to be local time. Unambiguous input (with offset) is adjusted to local time.
Example:
moment(data['dateString']).format('DD-MMM-YYYY');
NOTE: depending on your sites use case (especially if you plan to have global visitors), it may be a good idea to store the date in UTC for translation purposes like this. To ensure everyone sees the date relative to their location.

Categories

Resources