Java: What is the absolut first second in Calendar? - java

For example I have this:
Calendar result = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
result.setTime(new Date(0))
This should be the start of Calendar (1. Januar 1970 ...), but what is really the first second since epoche? Or more precise: What timezone with 0 milliseconds since epoche is the earliest?
Is it "Pacific/Kiritimati" the first?

To be precise UTC is not a timezone, it is a time standard. To be formally correct no country/territory is using UTC "timezone". But from a very basic view UTC is similar to GMT. So first second since epoche is one second after midnight in GMT (in 1.1.1970).
Also note, that countries that use GMT switch to different timezone when they apply daylight saving time. E.g. UK switches BST which is +01:00 from GMT

Related

Java Date start epoch

The java.util.Date class is based on the number of seconds since 1 January 1970 00:00 GMT. So why does this code
System.out.println(new Date(0));
print Thu Jan 01 01:00:00 GMT 1970? My local time zone is GMT, so I expected it to print 00:00:00 GMT.
There is an interesting reason for this. Refer (BST Offset bug report)
.
It says, "and the experiment with British Standard Time from 1968 to 1972, by which the time was advanced by one hour from GMT throughout the year." And further: “The local time produced by Date.toString() is historically correct, except for the time zone abbreviation. It should be "BST" (British Standard Time for this case), but it's a known limitation of the current TimeZone implementation.”
This link might help. I'm quite a novice at the Date class, but I figured this could help somehow.
Unix Epoch Time is a system of time describing how much time has elapsed since January 1st, 1970.
Therefore, when you create a new java.util.Date object with 0 milliseconds elapsed, it will return January 1st, 1970.
What you are looking for is here.

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.

joda time to Date inconsistent time zones

I have a load of dates that I'd like to store in a database running on a server using BST:
2015-09-23
2024-05-07
2024-03-13
However they are stored in the DB as:
2015-09-23 01:00:00
2024-05-07 01:00:00
2024-03-13 00:00:00 <-- I need this to be 01:00:00
The values are converted to Date prior to being stored in the DB. I noticed the following when debugging:
TimeZone timeZone = Calendar.getInstance().getTimeZone();
System.out.println(timeZone.getDisplayName(false, TimeZone.SHORT));
System.out.println(new SimpleDateFormat("zzz").format(new Date()));
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC);
System.out.println(formatter.parseDateTime("2015-09-23").toDate());
System.out.println(formatter.parseDateTime("2024-05-07").toDate());
System.out.println(formatter.parseDateTime("2024-03-13").toDate());
The first two dates are using BST and the last one is GMT. Is is possible to make them all use the same time zone?
GMT
BST
Wed Sep 23 01:00:00 BST 2015
Tue May 07 01:00:00 BST 2024
Wed Mar 13 00:00:00 GMT 2024
First of all, keep in mind that java.util.Date doesn't have a timezone (more details about it can be read here).
What happens is that Date.toString() method uses the system's default timezone to print its value (check the value of TimeZone.getDefault() in your JVM, it'll probably be Europe/London).
And in Europe/London timezone, the offset is equals to UTC in the winter (which is printed as GMT) and is +01:00 in the summer (which is printed as BST, aka British Summer Time). These different 3-letter names denotes the offset change, but it doesn't mean the dates "changed" their timezone.
Also consider that timezone is not only the offset or the name, but the set of all offset changes that occur in a region during history (when the changes occur, and the offsets before and after each change).
So, the dates doesn't have different timezones, because:
In the same timezone there can be more than 1 offset. And some changes in the offset cause the change in the 3-letter name - although the use of these 3-letter names is widely used, they're ambiguous and not standard.
java.util.Date doesn't have a timezone, so it can't change it.
If you want to save these objects in a DB, what you should care about is the timestamp (the number of milliseconds from 1970-01-01T00:00:00Z), which is preserved when converting to Date.
If you check the timestamp millis in the objects created, you'll see that it wasn't changed:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC);
DateTime d1 = formatter.parseDateTime("2015-09-23");
DateTime d2 = formatter.parseDateTime("2024-05-07");
DateTime d3 = formatter.parseDateTime("2024-03-13");
// comparing timestamp millis between DateTime and java.util.Date
System.out.println(d1.getMillis() == d1.toDate().getTime());
System.out.println(d2.getMillis() == d2.toDate().getTime());
System.out.println(d3.getMillis() == d3.toDate().getTime());
All 3 cases above prints true, meaning that they represent the same instant in time (so the dates hasn't changed).
Actually, you can see that all DateTime objects were in UTC:
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
This prints:
2015-09-23T00:00:00.000Z
2024-05-07T00:00:00.000Z
2024-03-13T00:00:00.000Z
Conclusion:
you can save the Date objects without any problem, as their values are correct
if you want to display the dates to the user, you can use the DateTime objects (and use a DateTimeFormatter if you want a different format), because they don't use the default TimeZone in the toString() method.
Try this:
SimpleTimeZone UTCTimeZone = new SimpleTimeZone(0, "UTC");
TimeZone.setDefault(UTCTimeZone);
All the date object will use UTC as default timezone for you backend code

Java SimpleDateFormat gives different time zone for different day

I had a strange behaviour when parsing dates. Given
DateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
sdf.parse("25/10/2014") returns 25 Oct 2014 00:00:00 BST
while
sdf.parse("27/10/2014") returns 27 Oct 2014 00:00:00 GMT
I figured out that's because of the Daylight Time change, but surely I would expect the same time zone to be returned by the same parser. Or am I wrong?
Per the Wikipedia article on British Summer Time
During British Summer Time (BST), civil time in the United Kingdom is advanced one hour forward of Greenwich Mean Time (GMT), so that evenings have more daylight and mornings have less
BST begins at 01:00 GMT on the last Sunday of March and ends at 01:00 GMT (02:00 BST) on the last Sunday of October.
The last Sunday of October 2014 was the 26th. So, the TimeZone changed from British Summer Time to GMT as observed in the UK.
The default TimeZone is your system TimeZone, so when that changes your parser will too.
From the documentation of SimpleDateFormat#parse(String ParsePosition):
The TimeZone value may be overwritten, depending on the given
pattern and the time zone value in text. Any TimeZone
value that has previously been set by a call to setTimeZone()
may need to be restored for further operations.
So: No, the parser does not always return the same time zone.

Discrepancy in Converting Date to TimeStamp in java

I have a Date Object in following:
Date date=new Date("Mon, 05 May 2014 12:31:12 +0000")
I want to get Timestamp of date Object then :
date.getTime()
1399293072000
but this value not correct , correct value in following :
1399276872000
//*** for get timestamp use of http://www.epochconverter.com ***\\
why ?
First things first, from the JavaDoc for Date
Date(String s)
Deprecated.
As of JDK version 1.1, replaced by DateFormat.parse(String s).
So the constructor you are using has been deprecated since 1997!
Next, onto the JavaDoc for Date.parse which the construtor uses:
It accepts many syntaxes; in particular, it recognizes the IETF
standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also
understands the continental U.S. time-zone abbreviations, but for
general use, a time-zone offset should be used: "Sat, 12 Aug 1995
13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich
meridian). If no time zone is specified, the local time zone is
assumed. GMT and UTC are considered equivalent.
Empathsis mine.
So, what timezone are you in? Presumably not UTC.
You should specify local time zone while constructing Date object
Example:
Date date=new Date("Mon, 05 May 2014 12:31:12 GMT+0530");
Using Mon, 05 May 2014 12:31:12 +0000 at http://www.epochconverter.com I get 1399285872000 which is different from your timestamp.
Or you're passing different values, or there's a bug somewhere or
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
where the javadoc for java.util.Date.getTime() doesn't mention leap seconds.

Categories

Resources