Facing problem While Converting Date to MilliSeconds - java

In my Android Application, I am trying to convert Date/Time to Milliseconds, check the below code:
public long Date_to_MilliSeconds(int day, int month, int year, int hour, int minute)
{
Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("UTC"));
c.set(year, month, day, hour, minute, 00);
return c.getTimeInMillis();
}
Problem: I am getting 1290455340800(Nov 22 14:49:00 EST 2010) for Nov 22 19:49:00 EST 2010 (i.e. 5 hours back)
FYI, I am Currently in Indian TimeZone, but application can be executed from any country. so How do i exact Convert the date/time into the Milliseconds?

This line
c.setTimeZone(TimeZone.getTimeZone("UTC"));
Is probably causing the issue. There is no need to set the TimeZone as the current default is used.

My guess is that you're calling Date_to_MilliSeconds(22, 10, 2010, 19, 49). Your code explicitly uses UTC, so it's going to treat whatever you pass it in as UTC.
Just like your previous question (which makes me tempted to close this as a duplicate) it's unclear what you're really trying to do.
If you want to provide a local time to your method, you need to specify a local time zone. If you need to use a local time in the user's time zone, try setting the time zone to TimeZone.getDefault() - although I'd expect that to be the default anyway. If you want to provide a UTC time to your method, you need to specify a UTC time zone (as you are here).
What are you really trying to do?

In this piece of code, you are getting the amount of milliseconds since 01/01/1970 00:00 in your timezone for Nov 22 19:49:00 EST 2010 in UTC timezone. Why are you setting timezone to UTC?

The 5 hours difference is the difference between UTC and EST. You can use DateFormat.parse() to parse the input date if it's a string. Or you can use the code above and pass the desired timezone in c.setTimeZone() -- put in EST instead of UTC.

I'm using this:
public String timeToString(long time, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
sdf.setTimeZone(TimeZone.getDefault());
return sdf.format(time + TimeZone.getDefault().getRawOffset()
+ TimeZone.getDefault().getDSTSavings());
}
I think it solves the TimeZone problems.

Related

How to handle CST to CDT or vice versa using XMLGregorianCalendar

I had the below issue During daylight change CST-CDT reset.
Am getting the Input from Was8.5 server 2018-03-11-05.00 (UTC-5) as expected, but when it comes to WAS7 server, the below method returns Sun Mar 10 00.00.00 CST 2018 instead of Sun Mar 11 00.00.00 CDT 2018
/*
* Converts XMLGregorianCalendar to java.util.Date
*/
public static Date toDate(XMLGregorianCalendar calendar){
if(calendar == null) {
return null;
}
return calendar.toGregorianCalendar().getTime();
}
I know the server date/timezone reset didn’t take place properly, but in case if I want to get right Time when CST to CDT change or vise versa. How can I rewrite the code to convert XMLGregorianCalendar to java.util.Date in Java?
Something like,
If incoming request was CST(UTC-6), the toDate(XMLGregorianCalendar calendar) returns CDT (UTC-5). then I want toDate() should return CST (UTC-6).
the same way,
If incoming request was CDT(UTC-5), the toDate(XMLGregorianCalendar calendar) returns CST(UTC-6). then i want toDate() should return CDT(UTC-5).
java.util.Date doesn't have a timezone. It just have a long value that represents the number of milliseconds since unix epoch.
What you see (Sun Mar 10 00.00.00 CST 2018) is the result of toString() method, and it uses the JVM default timezone to convert the long value to a date and time in that timezone. See this article for more details:
https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
Anyway, one way to really know what's happening is to check this long value:
long millis = calendar.toGregorianCalendar().getTimeInMillis();
And then you can print this value in UTC:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss XXX");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(millis)));
Or, if you use Java 8:
System.out.println(Instant.ofEpochMilli(millis));
This will tell you the UTC instant that the Date corresponds to, so you can debug your code a little better than relying on Date::toString() method, which is confusing and misleading.
Regarding your main issue, I've tried to reproduce (I'm using Java 8 because it's easier to manipulate than using Date). First I created a date/time corresponding to 2018-03-11 in UTC-05:00, and I assumed the time to be midnight:
// March 11th 2018, midnight, UTC-05:00
OffsetDateTime odt = OffsetDateTime.parse("2018-03-11T00:00-05:00");
Then I converted this to America/Chicago timezone, which is a zone that uses CST/CDT:
// get the same instant in Central Time
ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("America/Chicago"));
Then I printed this:
// print the date/time with timezone abbreviation
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm xxx z", Locale.US);
System.out.println(zdt.format(fmt)); // 2018-03-10 23:00 -06:00 CST
Note that the result is 2018-03-10 23:00 -06:00 CST: March 10th in UTC-06:00.
That's because in 2018, Daylight Saving Time starts only at 2 AM of March 11th. At midnight, DST has not started yet, so the offset is still UTC-06:00.
Anyway, your conversion code is correct, because Date just represents a point in time (a count of elapsed time since epoch) and doesn't have timezone attached to it. Perhaps the problem lies somewhere, and checking the millis value might help you to understand what's going on (my guess is that XmlGregorianCalendar sets the time to midnight when it's not present, which would explain the result of Sun Mar 10 00.00.00 CST 2018).
If that helps, the exact UTC instant where DST transition occurs (March 11th 2018 at 2 AM in UTC-06:00) corresponds to the millis value 1520755200000. If your dates in March 2018 have a value lower than that, it means they're before DST starts, and they'll be in CST.
My first suggestion is that you don’t need what you are asking for. As I see it, you’ve got a date and a UTC offset, and I don’t really see that the offset adds any useful information. Just take the date. I believe what has happened was that a point in time after the transition to summer time on March 11 was stripped of the time-of-day, but the UTC offset was kept for whatever reason or maybe for no reason at all. When giving the time at start of day (00:00), the offset disagrees with your time zone of America/Chicago (or Central Time Zone, but the ID in region/city format is unambiguous and recommended).
And don’t use java.util.Date for your date. That class is long outdated. Today we have so much better in java.time, the modern Java date and time API. Furthermore its LocalDate class is better suited for a date without time-of-day because this is exactly what it is, while a Date is really a point a in time, that is, a whole different story. Depending on taste conversion from XMLGregorianCalendar can happen in two ways.
The direct way
return LocalDate.of(calendar.getYear(), calendar.getMonth(), calendar.getDay());
With your XMLGregorianCalendar of 2018-03-11-05:00 the result is a LocalDate of 2018-03-11.
The indirect way via GregorianCalendar and ZonedDateTime:
return calendar.toGregorianCalendar().toZonedDateTime().toLocalDate();
The result is the same. The advantage of the latter is you don’t need to concern yourself with the individual fields of year, month and day-of-month. Among other things this means you don’t risk putting them in the wrong order.
If you do insist on keeping the time zone or UTC offset, at least take the offset. Sun Mar 11 00.00.00 CDT 2018 doesn’t make sense because March 11 at 00:00 hours DST was not yet in effect (it began at 02:00). Such a non-existing time will just confuse everyone. Convert your calendar object to OffsetDateTime:
return calendar.toGregorianCalendar().toZonedDateTime().toOffsetDateTime();
Result: 2018-03-11T00:00-05:00. This point in time exists.:-)
Since your calendar comes from a foreign system, you will probably want to validate it since any field may be undefined and return DatatypeConstants.FIELD_UNDEFINED. When using LocalDate.of(), you may decide that its argument validation is enough since it will object to DatatypeConstants.FIELD_UNDEFINED being passed as an argument. toGregorianCalendar() on the other hand will tacitly use default values, so when using it I would consider validation indispensable.
What went wrong in your code?
I ran your code, and similarly to iolus (see the other answer) I got Sat Mar 10 23:00:00 CST 2018. This the correct point in time. As iolus also explained, this is Date.toString rendering the point in time this way. The Date object itself doesn’t have a time zone or UTC offset in it. So I should say that your code was correct. It was just you getting confused by the toString method. Many have been before you, and the good solution is to avoid the Date class completely. Also I would think that your observations have nothing to do with any difference between WAS 7 and WAS 8.5.

How to set a date in certain timezone? [duplicate]

This question already has answers here:
How to set time zone of a java.util.Date?
(12 answers)
Closed 5 years ago.
I am using timer to perform certain tasks in certain period. This method requires Date type if you want to make the task start from that date and repeat in every period.
I have been trying to find solution for this for hours but couldn't come up with anything. I create calendar and set a timezone for it. Then when I get date from that calendar this date contains my LOCAL TIME. I tried getting string from Date using SimpleDataFormat and it worked because you set timezone for SimpleDataFormat separately. Then even tried parsing that string into the date but it still didn't work. I'm kinda hopeless at this moment. What's the point of setting timezone for calendar if I'm not able to use it. I could still do something if it wasn't getting my local time but instead it was getting UTC. But that's not the case either. I don't want to make this application run based on the computer's local time. That's absurd it should be able to get local time and turn it into the time zone I want and use it like that.
Code:
TimeZone eu = TimeZone.getTimeZone("GMT+1");
TimeZone america = TimeZone.getTimeZone("EST");
TimeZone asia = TimeZone.getTimeZone("GMT+7");
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
df.setTimeZone(eu);
Calendar euCal = Calendar.getInstance(eu);
Date dateEu = euCal.getTime();
System.out.println(dateEu); //Prints local time date
euCal.setTimeZone(eu);
System.out.println(dateEu); //Still prints local time date
String formattedDateEu = df.format(dateEu);
System.out.println(formattedDateEu); //This one works fine but it is string
try {
dateEu = df.parse(formattedDateEu);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(dateEu); //Fun part. Although I don't get exception dateEu is still not in the time zone I want.
Sample Output:
Mon Nov 27 14:37:21 MSK 2017
Mon Nov 27 14:37:21 MSK 2017
27/11/2017 12:37:21
Mon Nov 27 14:37:21 MSK 2017
java.util.Date objects don't contain time zone information. They represent an instant in the time continuum that is the same instant for everyone regardless of whether they so happen to be in Paris or New York at the moment.
However, when you try to print a Date object with System.out.println() it needs to try and describe itself. So it will need to describe the date and time it represents, but to do that it first needs to choose a time zone to represent this date and time in, since it doesn't have one. For convenience it chooses the user's system time zone.
You're not going to use your Date by calling System.out.println() with it, so you shouldn't care what System.out.println() does with it.
I wish I could tell you to stay away from the long outdated Date class. Today we have so much better in java.time, the modern Java date and time API. However, you are correct that java.util.Timer does need a Date for scheduling a task at a specific date and time. Still, since the modern API is so much nicer to work with, I recommend you use it for initializing your Date:
ZoneOffset eu = ZoneOffset.ofHours(1);
ZoneOffset america = ZoneOffset.ofHours(-5);
ZoneOffset asia = ZoneOffset.ofHours(7);
OffsetDateTime euTime = OffsetDateTime.now(eu);
System.out.println(euTime);
Date dateEu = Date.from(euTime.toInstant());
// schedule to start at the specified date-time and repeat weekly
myJavaUtilTimer.scheduleAtFixedRate(myTask, dateEu, TimeUnit.DAYS.toMillis(7));
I appears to me you aren’t really using time zones, just offsets from GMT (or UTC). So I put in some ZoneOffsets in the code. The result of printing euTime just now was
2017-11-27T15:56:03.213+01:00
You can see that the offset is +01:00 as expected. Then, as kumesana already said in the other answer, don’t print the resulting Date, just trust that it’s OK.
If you do prefer real time zones, use for example:
ZoneId eu = ZoneId.of("Europe/Brussels");
ZoneId america = ZoneId.of("America/Jamaica");
ZoneId asia = ZoneId.of("Asia/Krasnoyarsk");
The rest of the code is the same. That’s true: OffsetDateTime.now() accepts either a ZoneOffset or a ZoneId, so you can even mix both types. Of the above time zones, Europe/Brussels uses summer time (DST), so you will get an offset of +02:00 during 7 months of the year.
Avoid the three letter time zone abbreviations like EST. They are often ambiguous. Do prefer to specify your time zones in the region/city format as I do in my code.
EDIT: Here’s an example run from my computer:
2017-11-28T19:04:22.917+01:00
myTask running # 2017-11-28T19:04:23.156+01:00[Europe/Oslo]
As you can see, myTask ran 239 milliseconds after the specified firstTime for the scheduled task. Such latency should be expected. In a second run, the difference was down to 130 ms.

How to Get UTC DateTime

How can I get UTC DateTime from the following code? Right now with these lines of code, I get an output like this Fri Dec 31 05:30:00 IST 9999. Is this output is correct? I mean to say is this time is the UTC time. Any suggestions or help?
Code snapshot
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(9999, 11, 31, 0, 0, 0);
Date date = cal.getTime();
System.out.println(date);
Well, the output is correct in that it's what I'd expect for midnight UTC when you're running on a system in IST. Date.toString() always uses your system local time zone - because it doesn't have any other information. A Calendar knows its time zone, but a Date doesn't. The underlying information is just "the number of milliseconds since the Unix epoch".
If you want to convert a Date to a textual representation in a particular time zone, use SimpleDateFormat and specify the time zone there.
The problem here is that you're using the Date.toString() method that returns the local time zone.
You can use this code to get the current time in UTC:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
And then just use that object to get the time you want and use it, do note that cal.getTimeInMillis() or getTime() both return the time from the Epoch that is set to January 1, 1970 00:00:00.000 GMT (Gregorian). So if you want to print the time or use it for something other then calculate the difference in time you can use, for example:
System.out.println(cal.get(Calendar.YEAR));
However if you want to get the difference of time between this time and another you should create another calendar instance for that other time (because of the way getTimeInMillis() work). So you can just do something like:
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
time.set(Calendar.YEAR, year);
time.set(Calendar.MONTH, month);
time.set(Calendar.DAY_OF_MONTH, day_of_month);
time.set(Calendar.HOUR_OF_DAY, hour_of_day);
time.set(Calendar.MINUTE, minute);
time.set(Calendar.SECOND, second);
long difInMillis = cal.getTimeInMillis() - time.getTimeInMillis();
Also you should always remember that the month starts from 0 and not from 1, to be sure you can use Calendar.[your_month_here] and check the values.
You can find more information here: http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

Difference between new Date() and Calendar date

What is the difference between the two dates below in practice?
Date date = new Date();
Date date = Calendar.getInstance().getTime();
What I understand is that new Date() is a UTC/GMT based date while calendar's getTime() is based on TimeZone & System time. Am I right? Do I miss something still?
Moreover, if my above understanding is correct, can I say that the end results of the following two functions are exactly the same ?
1.
public String getDate1(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//I set the time zone & pass the new Date()
sdf.setTimeZone(TimeZone.getDefault());
return sdf.format(new Date());
}
2.
public String getDate2(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//I didn't set the time zone because I think calendar instance will handle timezone change
return sdf.format(Calendar.getInstance().getTime());
}
I appreciate if you could point out where I understand wrongly & explain to me clearly. Because I feel this thing is confused to me. Thanks!
Practical info about Java Calendar and Date
If you want to operate with different dates in your Java program you will use Java Calendar class.
I will try to give you some overview of not widely known facts about Java Calendar and Date classes, working code examples, which you can try right away.
The basic information about Calendar class is provided by Java API. The Calendar class is about days, months and years. One could ask: is not Date class about the same? Not exactly...
What is difference between Java Date and Calendar classes?
The difference between Date and Calendar is that Date class operates with specific instant in time and Calendar operates with difference between two dates. The Calendar class gives you possibility for converting between a specific instant in time and a set of calendar fields such as HOUR, YEAR, MONTH, DAY_OF_MONTH. You can also manipulate with the calendar fields, for example getting the date of your grandmother birthday :).
I would like to point some things about Calendar and Date which you should know and which are not obvious...
Leap seconds.
Years, months, dates and hours are in "normal" range like:
A year y - 1900.
A month from 0 to 11
A date (day of month) from 1 to 31 in the usual manner. calendar leap seconds
An hour 0 to 23.
A minute from 0 to 59 in the usual manner.
But, attention!! A second is represented by an integer from 0 to 61. Looks strange - 61 second, but do not forget about leap second. About once every year or two there is an extra second, called a "leap second." The leap second is always added as the last second of the day, and always on December 31 or June 30. For example, the last minute of the year 1995 was 61 seconds long, thanks to an added leap second.
Lenient fields.
Another funny feature is lenient and non-lenient fields in calendar. What is that? Example:
32 January 2006. Actually if you set your calendar lenient it will be 1 February 2006 and no problem for your program :). If it is non-lenient ArrayIndexOutOfBoundsException exception will be thrown.
Another question is 00:00 end or beginning of day? Is 00:00 A.M. or P.M.? Are midnight and noon A.M. or P.M?
Answer: 23:59 is the last minute of the day and 00:00 is the first minute of the next day. Midnight belongs to "am", and noon belongs to "pm", so on the same day, 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm.
And probably last question: what is epoch? and why this Epoch since January 1, 1970 00:00:00.000 GMT.
Actually it is Unix time, or POSIX time, is a system for describing points in time: it is the number of seconds after 00:00:00 UTC, January 1, 1970.
Wait, one question more!
"If we use the time which is counted since Epoch, how can I know which years had leap seconds and which not?"
Answer: To make life easier leap seconds are not counted. Java Date class takes actual time from OS and most of modern computers can not use leap seconds, their's internal clocks are not so precised. That's why periodical time synchronization is required.
There is no difference between at all between those two dates. (The second one is of course a bit wasteful in allocating a Calendar object that you don't use.)
An instance of java.util.Date is an absolute point in time. It has no knowledge of time zones. Setting the Default timezone on the SimpleDateFormat similarly does nothing, it uses the default by.... default!
To try to explain in different terms, the java.util.Date for
10:49 pm Dec 19, 2013 UTC
And
5:49 pm Dec 19, 2013 US Eastern Time
Is exactly the same object. The exact same java.util.Date represents both of those human-readable representations of time. The human-readable considerations only come into play when you use the formatter to turn it back and forth. (Hence why you set the timezone on the formatter, not on the date, date has no knowledge of what a timezone means.)
In 2022, you MUST use java.time classes and you can refer here to know almost everything that needs to be known about time. But if you are using Java versions older than 8, or if you are curious, read on for some high-level overview.
1. Date date = new Date(); //Thu Mar 24 04:15:37 GMT 2022
2. Date date = Calendar.getInstance().getTime(); //Thu Mar 24 04:15:37 GMT 2022
Date(Does not have a notion of timezone, and is mutable, i.e not thread-safe)
Date is sufficient if you need only a current timestamp in your
application, and you do not need to operate on dates, e.g., one-week
later. You can further use SimpleDateFormat to control the date/time
display format.
Calendar(Abstract class, concrete implementation is GregorianCalendar)
Calendar provides internationalization support. Looking into the
source code reveals that: getInstance() returns a GregorianCalendar
instance for all locales, (except BuddhistCalendar for Thai ("th_TH")
and JapaneseImperialCalendar for Japanese ("ja_JP")).
Trivia
If you look at the Date java documentation, you will see many deprecated methods and the note:As of JDK version 1.1, replaced by Calendar.XXX. This means Calendar was a failed attempt to fix the issues that Date class had.
Bonus
You might want to watch this to get some more insights of Date vs Calendar

Time Zones in Java / GWT (Client-side)

[Client-side GWT class]
I have a Date Object...
Date dataObject = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
.parse("2009-10-12T00:00:00.000);
This works fine. However when I do a:
dateObject.getTime();
It returns a UNIX Time milliseconds using a GMT with daylight savings, therefore making it a UNIX Time I cannot use. I need it in UTC. How do I do this?
Currently I'm parsing a date and it is giving me back:
'Thu Apr 16 08:46:20 GMT+100 2009' # '1239867980191'
However the date I'm passing in is 1 hour less than this time (7:46 and not 8:46!).
How do I pass in the fact it's UTC? Or if it can't use UTC (which would be ridiculous), how do I use GMT without the daylight savings?
Your last edit makes things clearer.
Basically, you are confused, and you already get what you want.
1239867980191 milliseconds since the Epoch translates to Thursday, April 16th, 2009, at 7:46:20.191 in the GMT time zone. The very same instant translates to the same day, but 8:46:20.191 in the GMT+01 time zone. If your input string specified "7:46:20.191" and you indeed got 1239867980191 from Date.getTime() then congratulations, the parsing code understood your "7:46:20.191" as to be interpreted in the GMT time zone, and did it properly.
If afterwards you get "8:46:20" when printing, this is only because you use the GMT+01 time zone for displaying that instant. Note that the string contains GMT+100 precisely to notify you that it uses that time zone for display purposes. The instant which the Date instance represents is nonetheless exactly the instant you wish it to contain. Remember that a Date instance represents an instant in time, for which no notion of time zone applies: time zones are used to convert instants into calendar elements (days, hours...) and back.
To convert a Date to a displayable string, use DateTimeFormat.format(Date, TimeZone) which lets you specify which time zone you want to use for that string.
Since the Calendar class is not supported in GWT, maybe something hackish like this will work:
final String timezone = "GMT-07:00";
DateTimeFormat dtf = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ");
long unix = dtf.parse("2009-10-12T00:00:00" + timezone).getTime();
This way you can provide the correct timezone info - though, that should be the default behaviour.
It is the other way round. A Date instance holds the time in milliseconds since the Epoch, using the UTC time scale (i.e. leap seconds are ignored). This is what Date.getTime() returns and that's what you want.
The culprit here is the parser, which interprets the date you give as a string in your local time zone. If you want DateTimeFormat to interpret the string as a date-and-time given in the UTC time zone, append an explicit time zone to the parsed string:
DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ")
.parse("2009-10-12T00:00:00.000" + " GMT");
(The above assumes that I understood GWT documentation properly; I have not tried.)
Just to be clear in my notations: for all practical purposes, there is no difference between "GMT" and "UTC", and there is no daylight saving in the GMT time zone. Other time zones are often defined as "GMT plus or minus some offset" and the offset may change between summer and winter. For instance, the time zone in New York is somewhat equivalent to "GMT-04" in summer and "GMT-05" in winter.
I keep seeing formats with ZZZZ being suggested... but why?
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" would match
"2009-10-12T00:00:00.000-0000"
The last part being the offset from UTC; California (to use someone else's example time) would be -0800, -0700 in summer.
As a side note, GMT is also always -0000. That's why Britain's summer time zone is BST (British Summer Time, +0100).
Try the Calendar object.
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Date dataObject = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
.parse("2009-10-12T00:00:00.000);
cal.setTime(dataObject);
cal.getTimeInMillis();
According to the API, getTimeInMillis() returns "the current time as UTC milliseconds from the epoch."
EDIT: as _bravado pointed out, the Calendar API is currently not available for GWT (Issue 603). While this would get the appropriate time in a Java application, it isn't going to work here. There is information in the group about using GMT.
EDIT: Missing a closing bracket on the the Calendar.getInstance() call

Categories