I have a problem whereby the number of days since epoch returned by Joda-Time library changes depending the time of the date I entered. If I enter 2012-05-14 22:00:00 and 2012-05-14 02:00:00 I would expect the same result since they are both on the same day. The following is my code.
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = sdf.parse("2013-05-03 07:00:00");
Date date2 = sdf.parse("2013-05-03 23:30:00");
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(0); //Set to Epoch time
System.out.println("Epoch: " + epoch);
Days days1 = Days.daysBetween(epoch, new MutableDateTime(date1.getTime()));
Days days2 = Days.daysBetween(epoch, new MutableDateTime(date2.getTime()));
System.out.println("1) Days Since Epoch: " + days1.getDays());
System.out.println("2) Days Since Epoch: " + days2.getDays());
} catch (ParseException e) {
e.printStackTrace();
}
Epoch: 1970-01-01T11:09:00.414+01:00
1) Days Since Epoch: 15827
2) Days Since Epoch: 15828
Does anyone have any idea what I'm doing wrong?
OK found the problem (which was in front of my own eyes :)) ... the epoch I was getting was indeed starting from 1970-01-01 but not from the very first ms of that day.
I needed to add the following line to get it sorted:
epoch.setTime(0);
Related
I want count of days starting from epoch(1970-01-01). I tried with joda-time
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = sdf.parse("2013-05-03 07:00:00");
Date date2 = sdf.parse("2013-05-03 23:30:00");
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(0); //Set to Epoch time
System.out.println("Epoch: " + epoch);
Days days1 = Days.daysBetween(epoch, new MutableDateTime(date1.getTime()));
Days days2 = Days.daysBetween(epoch, new MutableDateTime(date2.getTime()));
System.out.println("1) Days Since Epoch: " + days1.getDays());
System.out.println("2) Days Since Epoch: " + days2.getDays());
} catch (ParseException e) {
e.printStackTrace();
}
and using logic:
// Create Calendar instance
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);
// Set the values for the calendar fields YEAR, MONTH, and DAY_OF_MONTH.
// calendar1.set(calendar1.YEAR, calendar1.MONTH, Calendar.DAY_OF_MONTH);
calendar1.set(1970, 1, 1);
/*
* Use getTimeInMillis() method to get the Calendar's time value in
* milliseconds. This method returns the current time as UTC
* milliseconds from the epoch
*/
long miliSecondForDate1 = calendar1.getTimeInMillis();
long miliSecondForDate2 = calendar2.getTimeInMillis();
// Calculate the difference in millisecond between two dates
long diffInMilis = miliSecondForDate2 - miliSecondForDate1;
/*
* Now we have difference between two date in form of millsecond we can
* easily convert it Minute / Hour / Days by dividing the difference
* with appropriate value. 1 Second : 1000 milisecond 1 Hour : 60 * 1000
* millisecond 1 Day : 24 * 60 * 1000 milisecond
*/
long diffInSecond = diffInMilis / 1000;
long diffInMinute = diffInMilis / (60 * 1000);
long diffInHour = diffInMilis / (60 * 60 * 1000);
long diffInDays = diffInMilis / (24 * 60 * 60 * 1000);
if(logger.isInfoEnabled()) {
logger.info("Difference in Seconds : " + diffInSecond);
logger.info("Difference in Minute : " + diffInMinute);
logger.info("Difference in Hours : " + diffInHour);
logger.info("Difference in Days : " + diffInDays);
}
I am getting diff result for both of this. can somebody help where i am wrong.
thanks.
The difference between 17006 and 17007 is one day. This difference very likely comes from 7:00 and 23:30 in your time zone are on different days in some other time zone, say, UTC. Or the other way around, those times in UTC happen to be on different days in your time zone. Therefore the count is off by one. I don’t know JodaTime, so I cannot give you the precise details.
The difference between 16975 and 17006 is 31 days or a full month. I can tell you exactly where this comes from. Calendar months are 0-based: January is month 0, February is 1, etc. So calendar1.set(1970, 1, 1) sets your Calendar to February 1, 1970, 31 days after the epoch. Use calendar1.set(1970, Calendar.JANUARY, 1) instead. You will also want to control the hours, minutes and seconds of the Calendar. You may call clear() before set() to make sure the time is at midnight.
If you can use Java 8, you may do:
DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
OffsetDateTime t1 = LocalDateTime.parse("2013-05-03 07:00:00", format)
.atOffset(ZoneOffset.UTC);
OffsetDateTime t2 = LocalDateTime.parse("2013-05-03 23:30:00", format)
.atOffset(ZoneOffset.UTC);
System.out.println("1) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t1));
System.out.println("2) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t2));
This prints:
1) Days Since Epoch: 15828
2) Days Since Epoch: 15828
If you want to use a different time zone:
DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
ZonedDateTime t1 = LocalDateTime.parse("2013-05-03 07:00:00", format)
.atZone(ZoneId.systemDefault());
ZonedDateTime t2 = LocalDateTime.parse("2013-05-03 23:30:00", format)
.atZone(ZoneId.systemDefault());
System.out.println("1) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t1));
System.out.println("2) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t2));
You can fill in the desired time zone instead of ZoneId.systemDefault().
I'm just doing a simple difference of two timemilisseconds of two different calendar.
Example:
Calendar ini = Calendar.getInstance();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {e.printStackTrace();}
Calendar end = Calendar.getInstance();
long diff = end.getTimeInMillis()-ini.getTimeInMillis();
System.out.println("diff "+diff);
System.out.println("ini date "+ ini.getTime());
System.out.println("end date "+ end.getTime());
System.out.println("diff time format "+timeFormat.format(diff));
The time format is:
private final static String TIME_STRING_FORMAT = "hh:mm:ss.SSS";
private static SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_STRING_FORMAT);
And in the output, always appear 1 our of difference, is it problem of the SimpleDateFormat???
Output:
diff 1500
ini date Sun May 24 22:27:01 CEST 2015
end date Sun May 24 22:27:03 CEST 2015
diff time format 01:00:01.500
Thanks for your help!!
It looks like SimpleDateFormat uses a timezone. See this related question. So when you give it the time 1500 milliseconds, it thinks you're giving it the time since the beginning of epoch time in the GMT time. Then it translates this to your timezone, giving you some hours of offset. You probably want to set the timezone on your timeFormat to GMT. Try this:
Calendar ini = Calendar.getInstance();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {e.printStackTrace();}
Calendar end = Calendar.getInstance();
long diff = end.getTimeInMillis()-ini.getTimeInMillis();
System.out.println("diff "+diff);
System.out.println("ini date "+ ini.getTime());
System.out.println("end date "+ end.getTime());
Date date = new Date(diff);
System.out.println(date);
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("diff time format "+timeFormat.format(date));
The 1 hour difference is caused by your local time zone. Date(long) constructs a date a number of milli seconds after January 1st 1970 GMT. In continental Europe (during winter) 1500 milli seconds after the epoch is thus January 1st 01:00:01.500.
If you use Java 8 see the tutorial on Period and Duration. Duration is probably what you want to use.
Yes, I know this question has been posed many times, but I am still unable to get a consistent result between .NET and Java.
There are a number of posts and google search results that refer to the constants:
long UNIX_EPOCH_IN_100NS_INTERVALS = 621355968000000000l;
long DOTNET_EPOCH_IN_MSEC_INTERVALS = -62135596800000l;
The first purports to be the number of 100ns intervals or 'tics' between UTC 0001-01-01 00:00:00 (z yyyy-MM-dd HH:mm:ss) and UTC 1970-01-02 00:00:00, and the second is the difference between the .NET epoch and the Java epoch in milliseconds.
A post here reports a similar issue in the .NET world.
In the code below, I calculate the offset between the epochs and then compare to the published numbers:
SimpleDateFormat sdf = new SimpleDateFormat("z yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date;
try {
date = sdf.parse("UTC 1970-01-01 00:00:00");
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("Stupid java dates !");
}
System.out.println("Unix Epoch Date: " + sdf.format(date));
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
System.out.println("Unix Epoch Milliseconds: " + cal.getTimeInMillis());
try {
date = sdf.parse("UTC 0001-01-01 00:00:00");
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("Stupid java dates !");
}
System.out.println("Calculated DotNet Epoch Date: " + sdf.format(date));
cal.setTime(date);
System.out.println("Calculated DotNet Epoch Milliseconds: " + cal.getTimeInMillis());
date = new Date(-62135596800000l);
System.out.println("Published DotNet Epoch Date: " + sdf.format(date));
cal.setTime(date);
System.out.println("Published DotNet Epoch Milliseconds: " + cal.getTimeInMillis());
which generates the output:
Unix Epoch Date: UTC 1970-01-01 00:00:00
Unix Epoch Milliseconds: 0
DotNet Epoch Date: UTC 0001-01-01 00:00:00
DotNet Epoch Milliseconds: -62135769600000
Published DotNet Epoch Date: UTC 0001-01-03 00:00:00
Published DotNet Epoch Milliseconds: -62135596800000
Any help appreciated.
I'm working on a security signature in java that also verifies the date and time the call is being made. The POST call arrives with something like
String date = "Sat, 27 Apr 2013 01:11:30 GMT"
SimpleDateFormat RFC1123Format = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
And I'm able to parse it
Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);
System.out.println("Date Header (GMT TIME): " + gmtTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + gmtTime.get(Calendar.HOUR_OF_DAY));
Calendar currentTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
currentTime.setTimeInMillis(System.currentTimeMillis());
System.out.println("System Date (LA TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (LA TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));
currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("System Date (GMT TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));
System.out.println("Diff: " + Math.abs(gmtTime.getTimeInMillis() - currentTime.getTimeInMillis()));
However the printout I get differs by 1 entire hour.
Date Header (GMT TIME): 1367025090000 ms
Hour of day (GMT TIME): 1
System Date (LA TIME): 1367022298441 ms
Hour of day (LA TIME): 0
System Date (GMT TIME): 1367022298441 ms
Hour of day (GMT TIME): 0
Diff: 2791559
Any ideas?
You can use JodaTime >> http://joda-time.sourceforge.net/ that implements TimeZone Calculations more efficiently than Java calendar
You don't give your formatter the calendar that you are using to represent your timestamps.
In this case, your calendar is set to represent timestamps in GMT. GMT is a synonym for UTC and UTC never observes any adjustment for DST. Your formatter, however, by default must convert your supplied string with the system default calendar as the basis, which likely does observe DST.
If this is the case, you can get consistent reporting by making sure that your formatter is using the same calendar that you are using to represent your date/times. Try this:
SimpleDateFormat RFC1123Format = new SimpleDateFormat();
GregorianCalendar gc - new GregorianCalendar(TimeZone.getTimeZone("GMT"));
RFC1123Format.setCalendar(gc);
RFC1123Format.applyPattern("EEE, dd MMM yyyyy HH:mm:ss z");
gc.setTime(RFC1123Format.parse(yourDateString));
Fixed it myself by adding an extra verification to check if Daylight Savings is being observed. This is the final code:
Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);
Calendar currentTime = Calendar.getInstance();
currentTime.setTimeInMillis(System.currentTimeMillis());
boolean DST = false;
if(currentTime.getTimeZone().inDaylightTime(currentTime.getTime())) {
DST = true;
}
currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));
if(DST) {
currentTime.set(Calendar.HOUR_OF_DAY, currentTime.get(Calendar.HOUR_OF_DAY) + 1);
.
.
.
<code to handle last day of month and month change as a result of the hour adjustment>
}
Thanks #gangqinlaohu for your suggestion.
I'm trying to get the number of days, weeks, months since Epoch in Java.
The Java Calendar class offers things like calendar.get(GregorianCalendar.DAY_OF_YEAR), or Calendar.get(GregorianCalendar.WEEK_OF_YEAR), which is a good start but it doesn't do exactly what I need.
Is there an elegant way to do this in Java?
You can use the Joda Time library to do this pretty easily - I use it for anything time related other than using the standard Java Date and Calendar classes. Take a look at the example below using the library:
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(0); //Set to Epoch time
DateTime now = new DateTime();
Days days = Days.daysBetween(epoch, now);
Weeks weeks = Weeks.weeksBetween(epoch, now);
Months months = Months.monthsBetween(epoch, now);
System.out.println("Days Since Epoch: " + days.getDays());
System.out.println("Weeks Since Epoch: " + weeks.getWeeks());
System.out.println("Months Since Epoch: " + months.getMonths());
When I run this I get the following output:
Days Since Epoch: 15122
Weeks Since Epoch: 2160
Months Since Epoch: 496
java.time
Use the java.time classes built into Java 8 and later.
LocalDate now = LocalDate.now();
LocalDate epoch = LocalDate.ofEpochDay(0);
System.out.println("Days: " + ChronoUnit.DAYS.between(epoch, now));
System.out.println("Weeks: " + ChronoUnit.WEEKS.between(epoch, now));
System.out.println("Months: " + ChronoUnit.MONTHS.between(epoch, now));
Output
Days: 16857
Weeks: 2408
Months: 553
I'm kind of surprised that almost all answers are actually calculating days between epoch and now. With java.time.LocalDate it's as simple as:
LocalDate.now().toEpochDay()
Long currentMilli = System.currentTimeMillis();
Long seconds = currentMilli / 1000;
Long minutes = seconds / 60;
Long hours = minutes / 60;
Long days = hours / 24;
System.out.println("Days since epoch : " + days);
or
System.out.println("Days since epoch : " + ((int) currentMilli / 86400000));
Calendar now = Calendar.getInstance();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0); // start at EPOCH
int days = 0
while (cal.getTimeInMillis() < now.getTimeInMillis()) {
days += 1
cal.add(Calendar.DAY_OF_MONTH, 1) // increment one day at a time
}
System.out.println("Days since EPOCH = " + days);
I wouldn't expect there to be an elegant way of doing it since it is not a very common requirement. I can't help but wonder why you want to do it...
But anyway, the way I would do it is to subtract the epoch date from the Calendar and then get the fields you want:
Calendar timeSinceEpoch = Calendar.getInstance();
timeSinceEpoch.add(Calendar.YEAR, -1970);
int yearsSinceEpoch = timeSinceEpoch.get(Calendar.YEAR);
int monthsSinceEpoch = timeSinceEpoch.get(Calendar.MONTH) + 12 * yearsSinceEpoch;
Date.getTime() - Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
You can use this and knowledge of how many milliseconds are in the intervals you care about to do the calculations.