How to Ignore User's Time Zone and Force Date() Use Specific Time Zone

How to ignore user's time zone and force Date() use specific time zone

A Date object's underlying value is actually in UTC. To prove this, notice that if you type new Date(0) you'll see something like: Wed Dec 31 1969 16:00:00 GMT-0800 (PST). 0 is treated as 0 in GMT, but .toString() method shows the local time.

Big note, UTC stands for Universal time code. The current time right now in 2 different places is the same UTC, but the output can be formatted differently.

What we need here is some formatting

var _date = new Date(1270544790922); 
// outputs > "Tue Apr 06 2010 02:06:30 GMT-0700 (PDT)", for me
_date.toLocaleString('fi-FI', { timeZone: 'Europe/Helsinki' });
// outputs > "6.4.2010 klo 12.06.30"
_date.toLocaleString('en-US', { timeZone: 'Europe/Helsinki' });
// outputs > "4/6/2010, 12:06:30 PM"

This works but.... you can't really use any of the other date methods for your purposes since they describe the user's timezone. What you want is a date object that's related to the Helsinki timezone. Your options at this point are to use some 3rd party library (I recommend this), or hack-up the date object so you can use most of it's methods.

Option 1 - a 3rd party like moment-timezone

moment(1270544790922).tz('Europe/Helsinki').format('YYYY-MM-DD HH:mm:ss')
// outputs > 2010-04-06 12:06:30
moment(1270544790922).tz('Europe/Helsinki').hour()
// outputs > 12

This looks a lot more elegant than what we're about to do next.

Option 2 - Hack up the date object

var currentHelsinkiHoursOffset = 2; // sometimes it is 3
var date = new Date(1270544790922);
var helsenkiOffset = currentHelsinkiHoursOffset*60*60000;
var userOffset = _date.getTimezoneOffset()*60000; // [min*60000 = ms]
var helsenkiTime = new Date(date.getTime()+ helsenkiOffset + userOffset);
// Outputs > Tue Apr 06 2010 12:06:30 GMT-0700 (PDT)

It still thinks it's GMT-0700 (PDT), but if you don't stare too hard you may be able to mistake that for a date object that's useful for your purposes.

I conveniently skipped a part. You need to be able to define currentHelsinkiOffset. If you can use date.getTimezoneOffset() on the server side, or just use some if statements to describe when the time zone changes will occur, that should solve your problem.

Conclusion - I think especially for this purpose you should use a date library like moment-timezone.

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

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")

Ignoring timezones when creating a date in javascript/momentjs

You can do this with moment.js using moment.utc().

http://momentjs.com/docs/#/parsing/utc/

moment([2011, 10, 8, 5]).format(); // different output based on timezone
moment.utc([2011, 10, 8, 5]).format(); // same output for all timezones

The way moment.utc works is by setting a flag internally to use getUTCMinutes instead of getMinutes, thus the output is the same in all timezones.

Display datetime with MomentJs without timezone conversion

Use the utc() method of moment to remove the timezone and display everything in universal time.

moment.utc('2015-01-22T16:11:36.36-07:00').format('l LT')

That will display the time as it is in UTC without any timezone offset. If you want to display the time as it was recorded in the user/server timezone you can parse the zone information when you construct a moment instance and have it use the timezone recorded in the parsed string.

moment.parseZone('2015-01-22T16:11:36.36-07:00').format('l LT');

With either of these approaches you should consider labeling the time in some way to reflect the timezone the time corresponds to. Failing to do this could lead to a lot of confusion for the end users.

How to get EST date time without changing Machine Time Zone and writing timezone conversion code?

The reason is I read somewhere in article that when you change currentculture the system would behave that way so DateTime.Now also should give me date in EST. Please correct me if I am wrong.

Ok, I will correct you. You are wrong (sorry).

DateTime.Now always returns the local time based on the operating system's local time zone setting. It is not affected by changes to CurrentCulture. Changing the current culture can affect the display format and the calendar system used when creating a string from a DateTime, but it does not affect the DateTime itself, and thus does not affect the time zone either.

In general, culture or locale settings are orthogonal to time zones. For example, if I am an English speaking American temporarily visiting Japan, my culture would likely be en-US, and my time zone would likely be Tokyo Standard Time.

Can I force Java to ignore timezones?

You get hit by the fact that Date is using an implied timezone.

A Dateis defined as milliseconds since "1970-01-01T00:00:00" UTC. So, the number of ms (for the internal value) will be different if a date(+time) String is being converted to a Date instance with different timezones being applied.

Not specifying an explicit timezone with the String-to-Date conversion and the conversion to a DB value does not imply the values are not subject to being related with a timezone.

As soon as this implied timezone is being changed "silently" without the code knowing, such change is observable as a time "warp".

Such "silent" timezone changes will e.g. happen at the following occasions (incomplete list!):

  • Sending a Date object instance accross the "wire", from one timezone to a different one
  • parsing a date at a timezone that is not the implied one associated with the value
  • (wrong) assumptions of code on the implicit timezone of a
    date/time value and trying to apply a false "correction" thereof.
    (E.g. when a timzone-less DB value is getting attributed an implied timezone from the DB that the reading application code tries to adjust to a (different) local timezone as assumed by the application.)

For overcomming that kind of trouble, there are basically two strategies:

  1. Strictly enforcing a unique timezone accross the whole application. (given the implicit semantics of Date using UTC will be a good choice.)

    IN that case, you would immediately convert any value being entered from "outside" to your common application timezone (from known or implied local timezone). And also only convert (internal) date/time values to local timezone for being displayed (as late as possible). Any value "inside" your application (and stored with the DB) will be in application timezone.

    This is invariant against changing timezone of servers and DB and only requires proper detection date I/O locations. You also need to take care of date/time values relating to other external entities (like the filenames you mention). Those values would best be generated according to application timezone in the first place.

  2. You give up trying to get by without notion of timezone and change to using explicit timezones with any date/time value.

The first approach has the benefit of providing consistent values accross different timezones (e.g. with generated file names using date/time value - that then needs to be used as UTC value).

The second one is easily providing consistent ordering of events from different timezones.

Doing the timezone conversion when storing/reading values from the
from DB has the potential risk of misinterpretations on the client that might live in a completely different timezone or change timezone between storing and retrieving such value (as you already suspected).


And to explicit address the question from the subject:

No, as long as you are using java Date class you will always refer to an implicit timezone on conversion from/to String while the internal value is based on UTC.

Moment js - get date without considering time zone

Have you tried parseZone?

moment.parseZone(end).format('MM/DD/YYYY');

That should keep your UTC offset applied. You can then also calculate the UTC offset, if you wanted to save that:

moment.parseZone(end).format('MM/DD/YYYY').utcOffset();

How can I completely ignore time zones in entire app?

Here's the thing. Ignore timezones except for two actions in your app:

  1. When showing dates/times to a user.
  2. When getting dates/times from a user.

Once you have an NSDate, forget timezones exist. Persist NSDate as-is. Do calculations with NSDate as-is. In a sense, this means everything is done in UTC time. It's all consistent. It's all uncomplicated.

You only worry about timezones when showing those dates to a user or when getting them from a user. That's it.

If you want the user's locale time, just use NSDateFormatter and its default timezone to show or get local times.

If you want to show or get times specific to an event, use an NSDateFormatter with its timezone set to the timezone of the event.

It's not any more complicated than this.

It always seems more complicated I think because people start logging NSDate and see what looks like the wrong time because they don't realize the output of the NSLog is in UTC time, not local time.

For example, you have a UIDatePicker for an event in London. Set the date picker's timezone to London time. Store the resulting NSDate. When you want to show the event's time to the user, set the timezone of the NSDateFormatter to London time. Then, no matter where the user is, it will show the proper London time.



Related Topics



Leave a reply



Submit