Dealing with saved epoch times when clocks change - java

I have an alarm clock app that uses the following two methods:
private void fastForwardAlarmToNext24Hours() {
// Get Alarm Time (unix)
DataStorageController alarmTimeController = new DataStorageController(getApplicationContext());
epochAlarmTime = alarmTimeController.getAlarmTime();
// Get Current Time (unix)
long epochCurrentTime = System.currentTimeMillis() / 1000L;
// While Alarm Time in the past, fast forward another 24 hours
while (epochAlarmTime < epochCurrentTime) {
epochAlarmTime = epochAlarmTime + (24*60*60); // Add a days worth of seconds
}
}
private Long getNumberOfSecondsUntilAlarm() {
long epochCurrentTime = System.currentTimeMillis() / 1000L;
return epochAlarmTime - epochCurrentTime;
}
This works fine and I get these sorts of results back:
SUMMER
10-12 07:46:26.678: D/CJS Logging(776): epochCurrentTime: 1381560386 10/12/2013 7:46:26 AM +1
10-12 07:46:26.678: D/CJS Logging(776): epochAlarmTime: 1381560480 10/12/2013 7:48:00 AM +1
However, when I forward the datetime of my device to the winter (post clocks change), I get the following result and the alarm fires 1 hour off:
WINTER
11-12 07:47:10.441: D/CJS Logging(942): epochCurrentTime: 1384242430 11/12/2013 7:47:10 AM +0
11-12 07:47:10.441: D/CJS Logging(942): epochAlarmTime: 1384325280 11/13/2013 6:48:00 AM +0
The reason this is happening is because the saved alarm time remains the same epoch time but when the clocks change that moves the local time by 1 hour.
Does anyone have any suggestions on how to deal with this?
Cheers, Charlie

Instead of using UNIX time, you may want to use local time instead, using Calendar instances:
// Get Current Time
Calendar currentTime = GregorianCalendar.getInstance();
// While Alarm Time in the past, fast forward a day
while (alarmTime.before(currentTime)) {
alarmTime.add(Calendar.DAY_OF_YEAR, 1);
}

Can you register for
http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_CHANGED
and update your next firing time?

The long value returned by System.currentTimeMillis() is always the the number of seconds after January 1, 1970 UTC.
Depending on how you initialize the timestamp, different values can displayed ( based on your locale/ machine / time etc ).
To keep it consistent, deal with your times internally using GMT ( or a timezone that does not have daylight savings ).

Related

Difference in Server UNIX time and device current time

I get Unix timestamp from server, it can be some order creation time:
1531740385
I need to show some data, 20 minutes after this time from server.
I tried this approach:
currentUnixTime = (int) (System.currentTimeMillis() / 1000L);
timeDifference = currentUnixTime - orderaddedtime;
if(timeDifference<1160){
show();
}
But it doesn't work if i change the time in android settings or change the time zone. How to get exact time difference?

How can I get a specific time Today in UTC java

I am trying to get a specific time in UTC for "today".
Say 5pm UTC
Instant.now().truncatedTo(ChronoUnit.DAYS).plus(1, ChronoUnit.DAYS)
OR
Instant.now().plus(1, ChronoUnit.DAYS).truncatedTo(ChronoUnit.DAYS)
This i believe gets me to midnight current day. Do I just extend this
Instant.now().truncatedTo(ChronoUnit.DAYS).plus(1, ChronoUnit.DAYS).minus(7, ChronoUnit.HOURS);
Or is there a better way to do this.
That would be something along these lines
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
// this would be the today (might be in the past)
ZonedDateTime result = now.with(LocalTime.of(17, 0));
if (result.isBefore(now)) {
// This would be "next time it is 5 o-clock".
result = result.plusDays(1);
}
// if you really want an Instant out of it.
return result.toInstant();

Modify date without modifying time

With JodaTime, without using the 'plus' or 'minus' functions and using the least lines of code, how can I set a new date without modifying the time?
My first attempt was to store the 'time' parts of the DateTime in separate ints using getHoursOfDay() and getMinutesOfHour() etc - then create a new DateTime with the required date and set the hours, minutes, and seconds back again. But this method is pretty clunky, and I was wondering if there was a less verbose method for doing this - ideally with just one line of code.
For example:
22/05/2013 13:40:02 >>>> 30/08/2014 13:40:02
Is JodaTime a must? Basic way to do this is
1. extract just time from timestamp.
2. add this to just date
long timestamp = System.currentTimeMillis(); //OK we have some timestamp
long justTime = timestamp % 1000 * 60 * 60 * 24;// just tiem contains just time part
long newTimestamp = getDateFromSomeSource();//now we have date from some source
justNewDate = newTimestamp - (newTimestamp % 1000 * 60 * 60 * 24);//extract just date
result = justNewDate + justTime;
Something like this.
Previously accepted answer were removed by moderator, as it contains only link to javadoc.
Here is edited version.
You could do it like this
DateTime myDate = ...
myDate.withDate(desiredYear, desiredMonth, desiredDayOfMonth);
JavaDoc is here: DateTime.withDate(int year, int month, int dayOfMonth)
use withFields like this:
new DateTime().withFields(new LocalDate(2000,1,1))
This will set all date time fields of the DateTime to those that are contained in the LocalDate - year, month and day in this case. This will work with any ReadablePartial implementation like YearMonth for example.

Google Calendar API: Event endTime is decremented by 1 day

I'm trying to use the Google Calendar API in my own Java class. Unfortunately, the endTime of the newly created event (vacation in this case) seems to decremented by 1 day.
Example: I create an event with startTime 2011-01-01 and endTime 2011-01-05 the event will show up in Google Calendar from 2011-01-01 to 2011-01-04.
This is what I got so far (just the date part, taken from the Google Calendar API Developer's Guide, changed to Date because I want All Day events):
...
CalendarEventEntry myEntry = new CalendarEventEntry();
DateTime startTime = DateTime.parseDate("2011-01-01");
DateTime endTime = DateTime.parseDate("2011-01-05");
When eventTimes = new When();
eventTimes.setStartTime(startTime);
eventTimes.setEndTime(endTime);
myEntry.addTime(eventTimes);
Reminder reminder = new Reminder();
reminder.setMethod(Method.NONE);
myEntry.getReminder().add(reminder);
CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);
...
Could this be somehow related to timezone issues? (I am from Germany)
When you don't provide DateTime.parseDate() with a time it will default to midnight. An event starting at midnight on the 1st and ending midnight on the 5th will display in the interface as running as full-day events from the 1st to the 4th. The time period doesn't include any time on the 5th, so it won't be displayed as being on the 5th.
You either need to set the end time as 2011-01-05 23:59, or add a day to the end date.

java.util.Calendar not reporting the correct timeInMillis

findCalendarStart: time into Calendar: 1260575897
findCalendarStart: set hour : 13
findCalendarStart: after hour : 1249775897
findCalendarStart: after hour string: Thu Jan 15 11:09:35 UTC 1970
findCalendarStart: set minutes : 13
findCalendarStart: after minutes: 1250015897
findCalendarStart: what calendar returns: 1250015897
I place a Date (initialized by passing long from a millisecond from today) in a Calendar. Calendar is correctly initialized. In the first calculation, I change the hour of day to 13. At this point, startCalTime.set(Calendar.HOUR_OF_DAY, ((new Integer(m.group(1)).intValue())*2)-1 );
I am passing the right hour of day values and minutes because Im seeing them in the logger. What could possibly be causing calendar to come up with such strange dates after I only change the hour of day from todays Date object?
More code:
Calendar startCalTime = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Date d = new Date(creationTime);
startCalTime.setTime(d);
startCalTime.getTimeInMillis();
..regex..
if(m.find()){
//SET HOUR OF DAY
_logger.warning("set hour 1 : " + new Integer((new Integer(m.group(1)).intValue())-1)); startCalTime.set(Calendar.HOUR_OF_DAY, new Integer(m.group(1)).intValue()-1 );
_logger.warning("after hour 1: " + new Long(startCalTime.getTime().getTime()));
_logger.warning("after hour 1 string: " + startCalTime.getTime().toString());
//SET MINUTE
_logger.warning("set minutes 1 : " + new Integer(m.group(2).toString()));
startCalTime.set(Calendar.MINUTE, new Integer(m.group(2)).intValue());
_logger.warning("after minutes 1: " + new Long(startCalTime.getTime().getTime()));}
Thanks,
culov
Let's see how you initialize your date. I suspect that instead of milliseconds, you are passing it seconds since epoch start - this (seconds, not milliseconds) is how regular Unix timestamps are defined. Java uses milliseconds for better granularity.
Calendar startCalTime = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Date d = new Date(creationTime);
What happens there? startCalTime and creationTime don't seem to be connected, I'd assume they should be?
Also for very slightly better performance/memory footprint, avoid new Integer/Long as much as possible and use Long/Integer.valueOf() instead.
Those times in your Calendar don't look right. If those are supposed to be times in milliseconds, then 126..... represents a time of only 350 hours, which looks to be off by almost 40 years.
The reason seems to be that your initialization is not really setting your calendar to today's date. The initial date seems to be just a few hours past the epoch.
Please post some more code and we can fix it for you.

Categories