Time zone conversion to CST based GMT offset - java

I have date(01-oct-2014), time (00:37:31), GMT difference(-360) now
I want to get the time conveted to CST. The solution can be in javascript
Or oracle databse.
I have read several articles but could'nt get any where..can some one help me out on this...

In Oracle, to convert your local time to time of another timezone, you need to CAST TIMESTAMP WITH TIMEZONE.
For example, I want to convert 'IST' Indian standard time, i.e. my local timezone to 'CST', i.e. Central :
SQL> WITH T AS
2 ( SELECT to_timestamp('10/01/2014 11','mm/dd/yyyy hh24') ist FROM dual
3 )
4 SELECT ist,
5 CAST(CAST(ist AS TIMESTAMP WITH TIME ZONE) at TIME zone 'CST' AS TIMESTAMP) cst
6 FROM t
7 /
IST CST
----------------------------------- ------------------------------
01-OCT-14 11.00.00.000000000 AM 01-OCT-14 12.30.00.000000 AM
Take care of Daylight saving. You might have to take care in understanding CST and CDT.

There are several ways to do this:
SELECT
(TIMESTAMP '2014-10-01 00:37:31') AT TIME ZONE 'CST',
FROM_TZ((TIMESTAMP '2014-10-01 00:37:31'), 'CST'),
CAST((TIMESTAMP '2014-10-01 00:37:31') AT TIME ZONE 'CST' AS TIMESTAMP)
FROM DUAL;
It depends if the result shall include the new time zone or not.

Related

Java : Mysql timestamp daylight saving bug

I have a particular table in mysql with a field refresh_time Type as timestamp.
In my code, I update the refresh_time field to a future date of next month. For that, I calculate the milliseconds for next month date using following logic :
periodRefresh = currentTime + MyServiceUtils.calculateNoOfDaysInMonth(currentTime)*86400000L;
And then the value periodRefresh (milliseconds) I convert to java.sql.Timestamp and pass it to db side to udpate the field :
new Timestamp(periodRefresh);
But what has happened was that the current date in db was 2021-04-03 15:57:13 and when the above logic was run to update the time to next month, same time, it updated the time as 2021-05-03 13:57:13 which is 2 hours less than expected.
Our server follows UTC timezone, but I see that the user was from Australia, and in that day (4th April 2021) there was a daylight savings time in AEST. But even then it doesn't add to above as if I convert 2021-04-03 15:57:13 UTC to AEST, it comes as 2021-04-03 01:57:13 and the daylight savings there is at 3 am.
All the above has confused me a bit with following questions:
If I am following UTC timezones, then also does sql.Timestamp and mysql can get affected by daylight saving time?
How is AEST daylight saving time affecting my Australia based user when I follow UTC timezone?
Even if DST was affecting, so it should have increased/decreased time by 1 hour, but how in my case a difference of 2 hours happened?
In MySQL, TIMESTAMP datatypes are always stored in tables as UTC. When you put them into the database, it first translates them from your connection's time_zone setting to UTC. And when you retrieve them it translates them the other way. This is not true of DATETIME data types.
This TIMESTAMP behavior is handy if you have a global app. You can ask each user for their preferred time zone, and store it as a user-preference setting.
If you take a raw (seconds since the UNIX epoch in UTC) TIMESTAMP value and add a month's worth of seconds to it, the resulting timestamp value may be in a different daylight-time regime. So it will be translated differently.
Either
do your timestamp processing in MySQL, for example with
UPDATE tbl SET periodRefresh = periodRefresh + INTERVAL 1 MONTH;
do it all in your app and use DATETIME, not TIMESTAMP, data types (to avoid the database's time zone translation, or
do it all in your app and use SET time_zone='UTC'; on every connection.

while converting to data object, Moscow time is one hour behind

In my application while converting to date object i am always getting one hour behind time . this issue in happening only with moscow time zone.
below is code :
MutableDateTime mdt = new MutableDateTime(time);
mdt.setSecondOfMinute(0);
mdt.setMinuteOfDay(0);
mdt.toDate()
in above code mdt.todate() returning 5/30/2021 23:00 instead of 5/31/2021 00:00.
jdk version : "1.8.0_191"
Edit: Why does "June 6 00:00" after conversion mdt.toDate() become "May 31 23:00"?
Your surprising observation probably comes from an old Joda-Time version with an old time zone database where Europe/Moscow was at offset +04:00 rather than +03:00. It was between 31 October 2010 and 26 October 2014. If Joda-Time “believes” that this is still the case, it sets your MutableDateTime to something like 2021-06-01T00:00:00.000+04:00 with offset +04:00 instead of +03:00. This corresponds to 2021-05-31T20:00Z UTC where the correct point in time would have been 2021-05-31T21:00Z UTC. In other words, it’s an hour too early. Therefore you get a Date that is an hour too early too. Your Java 1.8 “knows” that Moscow is at offset +03:00 these days and therefore prints the time as Mon May 31 23:00:00 MSK 2021.
Solutions include:
Upgrade to a newer version of Joda-Time that has an up-to-date time zone database.
Build your Joda-Time from sources for the version that you are using only with a newer bundled time zone database. This is explained on the Joda-Time home page, see the second link below.
Original answer
Your surprising observation probably comes from an old Java version with an old time zone database where Europe/Moscow was at offset +04:00 rather than +03:00. It was between 31 October 2010 and 26 October 2014. I have reproduced your result on my Java 1.7.0_67 and verified that my Java installation “believes” that Moscow is at offset +04:00 and does not use summer time (DST), as was the case in the mentioned period.
Your Joda-Time seems to be new enough to know that Europe/Moscow is at +03:00 so correctly converts your MutableDateTime to a Date at 00:00 hours on the date in question. Only when you print this Date, Java uses its default time zone, still Europe/Moscow, but its own time zone data, and therefore incorrectly prints the time as 01:00 hours instead of 00:00.
Possible solutions include:
Upgrade to a newer Java version that has up-to-date time zone data.
Fix your current Java installation by upgrading only its time zone database. See Timezone Updater Tool in the second link below.
Setting the time to the start of the day
Edit: you added:
Here MutableDateTime time =new MutableDateTime(new Date().getTime());
To get a Date representing the start of today’s date using Joda-Time:
Date oldfashionedDateObject = LocalDate.now(DateTimeZone.getDefault()).toDate();
System.out.println(oldfashionedDateObject);
Output just now:
Mon May 31 00:00:00 MSK 2021
Original aside: As an aside, the simpler and safer way to set the time to the start of the day is:
mdt = mdt.toDateTime().withTimeAtStartOfDay().toMutableDateTime();
If you need to keep the same MutableDateTime object, instead do:
mdt.setMillis(mdt.toDateTime().withTimeAtStartOfDay().toInstant());
First of all I would be worried that your code may run in a time zone and on a day that in that time zone has a transition at 00:00 so that the first moment of the day is 01:00 or something else. In this case I b believe that your code would throw a surprising exception. Also I find setting individual fields low-level and prefer to set everything in one method call even if it requires further operations to determine the argument to pass to that method.
Links
Time Zone in Moscow, Russia (Moskva).
Joda-Time Updating the time zone data.
Timezone Updater Tool on Oracle’s web site.

Java Hibernate Query with timezone

I need to create a query with my local time (+07:00). The server time is in GMT and all times stored in DB are in GMT too.
For example, today is June 18 I want to find records whose created_at (type: Date) is yesterday in my local time, which means the start date should be 2019-06-16 17:00:00.000 and the end date should be 2019-06-17 16:59:59.999. Is it possible to pass the timezone?

LocalDate inconsistency

I am trying to produce a Date object (java.util.Date) from a LocalDate object (java.time.LocalDate) in which I have the following criteria:
Allow a parameter that can subtract a certain number of days from the Date object
Have the Date & Time be the date and time currently in UTC
Have the time at the beginning of the day i.e. 00:00:00
The Timezone stamp (i.e. CDT or UTC) is irrelevant as I remove that from the String
To meet this criteria, I have created a test program, however I am getting interesting results when I modify a certain property of the LocalDate. See code below:
public static void main (String args[]) {
Long processingDaysInPast = 0L;
LocalDate createdDate1 = LocalDate.now(Clock.systemUTC()).minusDays(processingDaysInPast);
LocalDate createdDate2 = LocalDate.now(Clock.systemUTC()).minusDays(processingDaysInPast);
System.out.println(createdDate1);
System.out.println(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC));
System.out.println(Date.from(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC)));
System.out.println((createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
System.out.println(Date.from(createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
}
Output:
2017-08-14
2017-08-14T00:00:00Z
Sun Aug 13 19:00:00 CDT 2017
2017-08-14
2017-08-14T05:00:00Z
Mon Aug 14 00:00:00 CDT 2017
When I add the value Date.from(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC)) I get the expected output of the date, with a 00:00:00 time field. However, if I do not add this parameter, such as: Date.from(createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()) I get the resulting day before , at 19:00:00 why is this?
My main goal from this is to be able to capture a Date object, with the current UTC Date, and the Time zeroed out (StartOfDay).
When you do:
createdDate2.atStartOfDay().atZone(ZoneId.systemDefault())
First, createdDate2.atStartOfDay() returns a LocalDateTime, which will be equivalent to 2017-08-14 at midnight. A LocalDateTime is not timezone-aware.
When you call atZone(ZoneId.systemDefault()), it creates a ZonedDateTime with the respective date (2017-08-14) and time (midnight) in the system's default timezone (ZoneId.systemDefault()). And in your case, the default timezone is not UTC (it's "CDT", so it's getting midnight at CDT - just do System.out.println(ZoneId.systemDefault()) to check what your default timezone is).
To get the date at midnight in UTC, you can replace the default zone (ZoneId.systemDefault()) with UTC (ZoneOffset.UTC):
Date.from(createdDate2.atStartOfDay().atZone(ZoneOffset.UTC).toInstant())
Or (a shorter version):
Date.from(createdDate2.atStartOfDay(ZoneOffset.UTC).toInstant())
Of course you can also do the same way you did with createdDate1:
Date.from(createdDate2.atStartOfDay().toInstant(ZoneOffset.UTC))
They're all equivalent and will result in midnight at UTC.
Just a quick note: short timezone names like CDT or PST are not real timezones.
The API uses IANA timezones names (always in the format Region/City, like America/Chicago or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CDT or PST) because they are ambiguous and not standard.
There are lots of different timezones that can use CDT as abbreviation. This happens because a timezone is the set of all different offsets that a region had, has and will have during history. Just because many places uses CDT today, it doesn't mean they all used in the past at the same periods, nor that it'll be used by all in the future. As the history differs, a timezone is created for each region.

Getting Timezone Information from Long value in java

Can we get from which timezone the Long Value is produced?
I have long values of Date. I want to know from which timezone it is generated.
For e.g
Long value: 1435640400000
Date: 30 June 2015 CDT
I want to develop program which input will be the Date in long value
that will return output as Timezone with the respective
long value for 30 June 2015 12:00 AM GMT/UTC
The unix time (as it is called) is not a date. You can calculate a date from it but it really is just the duration of seconds (or ms) since 01/01/1970 at 00:00 UTC.
This means it has no timezone attached to it. You need the "target" timezone to calculate the actual date from it, but simply having this number does not include any timezone information (which means you'll need to get it somewhere else in order to calculate dates).
Think of the unix timestamp more as a duration than a date. It's like saying "I'll meet you in 30 minutes". Those 30 minutes do not have a timezone attached to them. To you and the person you're talking to, that meeting might happen at different dates (e.g. 2:30pm vs. 3:30pm) because of timezones. But it will still happen at the same point in time relative to the moment you said it.
I hope this makes the difference somewhat clearer.
There was a way to do this directly via the getTimezoneOffset() function in the Date class but that has been deprecated.
It has been replaced by
(Calendar.get(Calendar.ZONE_OFFSET) + Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)

Categories

Resources