Google Calendar API: Event endTime is decremented by 1 day - java

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.

Related

Different results with LocalDateTime by different calls with same parameter

The problem is, that I have to change my code from Calendar object to LocalDateTime object. But I don't get the same timestamp at the end. In the first call I got the same with localDateTime, on the next calls I get other timestamps and I use the same parameter to calculate the timestamps. I don't know why I get different results. It isn't logic for me. What I want to do is: I get a UTC Timestamp. I want to set it on german(Europe/Berlin) time(important about summer and winter season). Then I want to calculate the start of the day(00:00) and the end of the day(23:59). Then I want to get the timestamp for this times.
I build an API with spring-boot. The above described function is invoked by a controller class from spring-boot. The first call after the start of the API calculates the expected results. But all next calls give other results. Always with 7200 difference. I tried other ways with localDateTime, but it never gaves the same timestamp as with calendar.
LocalDateTimeWay:
LocalDateTime localDateTime =
LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
LocalDateTime dayStartLocal = localDateTime.withHour(0)
.withMinute(0)
.withSecond(0)
.withNano(0);
ZonedDateTime startZonedDateTime = dayStartLocal.atZone(ZoneId.systemDefault());
long dayStartTimeStamp = startZonedDateTime.toInstant().getEpochSecond();
LocalDateTime dayEndLocal = localDateTime.withHour(23)
.withMinute(59)
.withSecond(59)
.withNano(999);
ZonedDateTime endZonedDateTime = dayEndLocal.atZone(ZoneId.systemDefault());
long dayEndTimeStamp = endZonedDateTime.toInstant().getEpochSecond();
CalendarWay:
Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(timestamp*1000);
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
cal.set(Calendar.HOUR_OF_DAY,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
long dayStartTimeStamp = calendar.getTimeInMillis()/1000L;
cal.set(Calendar.HOUR_OF_DAY,23);
cal.set(Calendar.MINUTE,59);
cal.set(Calendar.SECOND,59);
cal.set(Calendar.MILLISECOND,999);
long dayEndTimeStamp = calendar.getTimeInMillis()/1000L;
I want by the param timestamp 1536933600. The result 1536876000 and 1536962399. But I get after the first request by localDateTime method 1536883200 and 1536969599.
You are using system default zone for your java.time code and Europe/Berlin zone for Calendar code. The 7200 is most likely the difference between your system time zone and Europe/Berlin (2 hours).
Replace all ZoneId.systemDefault() with ZoneId.of("Europe/Berlin") and you will get the same values in both versions:
timestamp = 1536933600
dayStartTimeStamp = 1536876000
dayEndTimeStamp = 1536962399

Quartz CronTrigger is not firing at the specified startAt() time

I have a scenario where I need to schedule a job which has to be execute daily at a specific time. When I schedule it with specific time as the start time for scheduler the quartz won't trigger the job at the set start time instead it would trigger at the next cycle i.e. after 24 hrs delay.Even on checking the the nextFireTime, we get a day's delay.
For E.g:
I need to schedule a job daily to run at 6 pm in the evening. And start it at 5 pm Today (27th March 2018).The job doesn't start and nextFireTime is 6pm 28th March 2018.
Code snippet :
Date startDateTime = new Date(scheduler.getStartDateTime());
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(startDateTime);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleTriggerName, schdeuleGroupName).startAt(startDateTime).withSchedule(dailyAtHourAndMinute(hours, minutes)).build();
JobDetail jobDetail = this.getJobDetail(schdeuleJobName, schdeuleGroupName);
Scheduler configuration for spring
SchedulerFactoryBean schedulerFactoryBean= new SchedulerFactoryBean();
QuartzAutowireBeanFactory jobFactory = new QuartzAutowireBeanFactory();
jobFactory.setApplicationContext(applicationContext);
schedulerFactoryBean.setJobFactory(jobFactory);
schedulerFactoryBean.scheduleJob(jobDetail, trigger)// scheduling the job
Solution
One liner:
Cron only handles 1-minute resolutions
The starttime that which was passed to the startAt() function was a timestamp till milliseconds and cron does support till minutes.
so the simple solution was to use the calendar to set the minutes and seconds as zero.
calendar.setTime(startDateTime);
calendar.set(Calendar.SECOND, 0); // this was the solution
calendar.set(Calendar.MILLISECOND, 0); // this was the solution
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
trigger = TriggerBuilder.newTrigger();
trigger.startAt(calendar.getTime()).withSchedule(dailyAtHourAndMinute(hours, minutes));
Detailed One:
Finally I got the reason for the behavior, while debugging I saw that it was setting the delay of 24 hours but when one would print the time it would be in hh:mm:00 format I mean the output would set the seconds parts as 00 as default , so the problem was the starttime that was passed as parameter was a timestamp through the UI consisting of seconds and milliseconds so after reading on the Cron format I came to know that it supported till minutes resolutions so wherever it use to get the timestamp the startAt(startDateTime) in the
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleTriggerName, schdeuleGroupName).startAt(startDateTime).withSchedule(dailyAtHourAndMinute(hours, minutes)).build();
it would calculate the next run by skipping the seconds and milliseconds part.

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.

Dealing with saved epoch times when clocks change

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 ).

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