I need to parse a custom defined date format, defined in a device that I need to communicate where the date is given as the number of seconds counted from the year 2000.
I tried to use GregorianCalendar
to parse this data, this is the code I tried:
GregorianCalendar calendar = new GregorianCalendar();
calendar.setGregorianChange(new Date(2000 - 1900, 0, 1));
The Date
object corresponds to January 1st 2000. And I thought that with this I was fine to setTimeInMillis
to get the correct date multiplying the time I read by 1000
, as it's counted in seconds not in miliseconds as GregorianCalendar
, but it didn't work. I tried setTimeInMillis(0)
, waiting that the time corresponding to calendar
corresponds to January 1st 2000 but it doesn't, it corresponds to December 18th 1969.
How can I configure GregorianCalendar
so I can setTimeInMillis(0)
and it corresponds to January 1st 2000? If it's not possible, is there any other class I can use instead of creating all the code by myself?
Thanks in advance.
setGregorianChange
only changes the point in time where the switch from Julian to Gregorian happened. It defaults to the correct historical value.
But since pretty much everyone else out there is using proleptic Gregorian, there is a valid use case for this function:
setGregorianChange(new Date(Long.MIN_VALUE)) //Julian never happened
This is also what JodaTime uses by default.
Anyway, you can just subtract 946684800000L
from the normal millisecond unix timestamp, and divide by 1000:
public static long secondsSince2000(Date input) {
final long epoch = 946684800000L;
return (input.getTime() - epoch) / 1000L;
}
To convert from seconds since 2000:
public static Calendar fromSecondsSince2000( long seconds ) {
final long epoch = 946684800000L;
Calendar cal = GregorianCalendar.getInstance();
long timestamp = epoch + seconds * 1000L;
cal.setTime(new Date(timestamp));
return cal;
}
To see that both are working:
long sec = secondsSince2000(new Date());
Calendar cal = fromSecondsSince2000( sec );
System.out.println(cal.getTime().toString().equals(new Date().toString()));
They should print true