I send timestamps to my GWT client using GMT/Zulu time, with each string designated as such (ie. 2012-01-19T16:29:18Z, or 4:29pm GMT). How do I show this in the browser in the local timezone? So for me in CST I expect to see 10:29am.
If I do no formatting I get the date as 4:29pm, which I expect, If I use a TimeZone object of TimeZone.createTimeZone(0), I get for some reason 10:29PM (not AM as expected). I suppose I'm supposed to pass in something more meaningful than 0, but how do I obtain the right value for the where the browser is running?
J
You can get the time-zone offset that is configured in the browser using:
Date d = new Date();
d.getTimezoneOffset();
It won't give you the timezone name, I don't think that's possible to get.
Do you send the time as a timestamp, or string? I find the best approach is to send UTC timestamps to the client and then format them to whatever zone I need using DateTimeFormat/TimeZone. But I guess that if you are parsing the date string including the offset, you end up with a UTC timestamp anyway.
If you want the GWT client code to format the time in the browser time zone, you should pass the data from the server to the client as a java.util.Date object.
Related
The DateTime created by DateTime.parse seems to always returns 0 for "timeZoneOffset"
I create a ISO8601 string here in a non UTC timezone: https://timestampgenerator.com/1610010318/+09:00
I pass that string to DateTime.parse:
DateTime date = DateTime.parse("2021-01-07T18:05:18+0900");
Issue: timeZoneOffset is 0 when I was expecting +0900.
print(date.timeZoneOffset); --> 0:00:00.000000
print(date.timeZoneName); --> UTC
print(date); --> 2021-01-07 09:05:18.000Z
Dart DateTime documentation (https://api.dart.dev/stable/2.10.4/dart-core/DateTime/parse.html):
The result is always in either local time or UTC. If a time zone offset other than UTC is specified, the time is converted to the equivalent UTC time.
Why is timeZoneOffset 0? What string do I need to pass to DateTime.parse to get it to store the time in local time instead of converting it to the equivalent UTC time?
The Dart SDK does not really handle different timezones which is the reason why the parse want local timezone (which is the timezone on the system running the program) or UTC.
If you are trying to parse a timestamp without any timezone information, Dart will assume the time are in local timezone (I am in Denmark which are using the Romance Standard Timezone):
void main() {
print(DateTime.parse("2021-01-07T18:05:18").timeZoneName); // Romance Standard Time
print(DateTime.parse("2021-01-07T18:05:18+0900").timeZoneName); // UTC
}
You can convert your UTC timestamp into localtime by using .toLocal() on the timestamp. But again, this will just convert it into the timezone which are on your own system and not the one coming from the time you have parsed:
void main() {
print(DateTime.parse("2021-01-07T18:05:18+0900").toLocal().timeZoneName); // Romance Standard Time
}
If you want to handle time with timezone data you should look into the package timezone: https://pub.dev/packages/timezone
Some notes about saving timezone offset
You should be aware that in most cases, it does not really makes sense to save the time in a form where you can get the original offset again. The problem is that most countries have rules like DST or the user are traveling and does expect the system to handle the time correctly.
So in a lot of cases, the user does not really expect to get the same offset back again but want the time to be with the currently offset based on location and time right now.
The timezone package does e.g. not allow you to parse a timestamp and save the offset together with it (because an offset is not the same as a location). Instead, it want you to specify the location the timestamp are used for so it can calculate the current offset for that location.
So in general, I recommend you to always save time as UTC on storage. When the data are going to be used, you should have some way to know the location of the receiver (e.g. ask the user in some form of profile) and convert the time to that location using the timezone package. If the application are running on a device owned by the receiver of the data, you can convert the UTC to local time using .toLocale().
I have a table that I am using to store iso dates with timezones. I realize that dates should "always" be stored as utc but I have an exception to that rule. The timestamps aren't in any way related to the server they are running on. I want to be able to store an iso date like this:
2016-03-06T01:15:52-06:00
And regardless of the time zone of the server or anything else I want the timestamp returned as:
2016-03-06T01:15:52-06:00
Currently if I insert an iso date it automatically converts it to whatever the server timezone is. My above date gets converted to:
2016-03-06 07:15:52+00 (server is utc)
The only thing I can think of is storing the timezone offset in a separate column, storing my date as utc and then converting using the offset column, horribly messy. Surely there is a way to store my date in one column and get it out the way it was originally created?
Your proposed solution is correct. Or more precisely, it is one of several correct implementations. Any of the following would work:
Store the UTC timestamp in one field, store the offset in another.
Store the local timestamp in one field, store the offset in another.
Store the local date in one field, and store a time with time zone in another. (though time with time zone is generally discouraged...)
Store the UTC timestamps in one field and the local timestamp in another.
The easiest by far is the first one, which you already proposed.
I'd avoid against storing timestamps in text fields, as they tend not to be very efficiently searchable.
Also note - if you're coming from a SQL Server background, you might recall its datetimeoffset type, which stores the local datetime and offset in the field, and uses the UTC equivalent during indexing. It's common to think that Postgres and MySQL's timestamp with time zone would have the same behavior, but they don't. They simply use the session time zone to convert to/from UTC. SQL Server has no concept of a session time zone, and thus the discrepancy.
Be sure to read this part of the Postgres docs.
I like to save the current DateTime.Now for the current user as UTC. For any user the time is than relative to each other ? I used this code snippet to realize UTC for the Entity Framework:
Entity Framework DateTime and UTC
After a look into the database the column for the date has not changed.
09.05.2014 20:21:24
I need to show on the client side the date relative to each user. So when the user created his account in America 14:00 I like to see in Europe 20:00.
First of all you need to use DateTime.UtcNow instead of DateTime.Now. EF will save date as it is, it will not do anything.
For database, it is just a date, whether it is UTC or specific time zone, database has no idea. It is only when we retrieve date from database, before displaying it to local user, we should call ToLocalTime or similar method in client UI library to convert UTC into localtime. ToLocalTime assumes that input is actually UTC.
If you are saving date from client side, for example with AJAX post in JavaScript, JavaScript dates should be serialized as UTC.
Remember that server has no idea from where you are sending date, server cannot convert any date to UTC, client on other hand has complete idea of which country and which timezone it is set at and it can easily convert local time into UTC.
Calling .ToLocalTime() on a DateTime object will convert it to the local time. You should always Save the date as UTC then convert upon display.
I have to format date/time in my gwt app with specific timezone, which is loaded from the server. Possible timezones are like this GMT, GMT+1, GMT-2 etc...
Up to now i used DateTimeFormat to format my timestamps, and they used client's locale.
PLease help.
You can format in any timezone you want with DateTimeFormat, you just have to pass it as the second argument to the format method.
And to obtain a TimeZone object, depending on how you want to present the timezone information (if ever) in the formatted date/time, you can use either createTimeZone(int) or createTimeZone(String) (getting the string out of TimeZoneConstants).
I'm using com.google.gwt.i18n.client.timezone to try and display a date (as at the server), but GWT automatically adds the current timezone to the date when formatting it, meaning The wrong date is shown in different timezones.
To combat this, I'm sending the server's timezone offset to the client and using that when formatting.
I live in Australia and the current timezone is +11 GMT/UTC, but the default timezone being displayed when I format the date is -11 GMT.
The offset from the server is +11 hours (as it should be), but when I try and format the date with this offset, I get the wrong date, and so I need to use the negative offset instead.
Why is the default timezone wrong?
When you are getting a date (particularly if you're parsing a date) make sure you specify the timezone. GWT's DateTimeFormat.parse only supports "RFC format" timezones, something like -0800 for Pacific time. If your server is sending dates in strings to the client, make sure it includes the timezone in this format.
Then when you convert the date to a string to present it to the user, make sure you use the overload of DateTimeFormat.format that specifies a TimeZone and pass the timezone that you want the date to be presented in (the timezone of the server, in your case.)
By default dates are presented in the timezone that the user's system is set to. Setting the default timezone in GWT (so you can ignore timezones and do everything in the server's timezone) is an open issue (3489) at the time I write this.