Date shifts one day off on click of save - java

They have used GWT to create a form which contains date pickers when user submits the form, dates selected shifts one day back. e.g. if i select 21/06/2015 it shifts to 20/06/2015. This is happening when users time zone is different from server time zone. When i debug it, i found that it shifts one day back while converting date to calendar because Date is client zone's Date and Date to Calendar conversion is happening in server side for sending it to marshalling(before sending request to rest service API for saving).
Following code is used for converting date to calendar.
Calendar cal = Calendar.getInstance();
int offset = date.getTimezoneOffset();
logger.info("Calendar Instance - " + cal);
cal.setTime(date);
logger.info("Calendar Instance after setting date - " + cal);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
logger.info("Calendar Instance after setting zeros - " + cal);
return cal;
In last log it displays one day less than actual date.
it works fine if i remove the following code.
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
for IST and PST but not to other timezones.
Please help.

Related

A function to convert minute since midnight to am/pm time

Is there an existing android or java or joda-time function for converting minutes since midnight to time? I know how to do it for a 24 hour period without the am/pm bit. But I need to have the am/pm for some users.
This is for an android app. So the added benefit of using a standard function is that it will conform to the general preference of the user.
I suppose I can roll out my (buggy) own if such does not exist.
You could use Calendar and SimpleDateFormat to get that. Something like,
static DateFormat _sdf = new SimpleDateFormat("hh:mm a");
static String minutesSinceMidnight(int minutes) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.AM_PM, Calendar.AM);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.MINUTE, minutes);
return _sdf.format(cal.getTime());
}

Inconsistent behavior with setting Java calendar object to midnight

I have a Java program where I need to set a Calendar object to be midnight, so I followed the instructions from another posting on how to create a Java Date object of midnight today and midnight tomorrow, where you set the fields to be 0, like so:
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
However, I am getting inconsistent results using Java 1.7.0_51. (Please no suggestions on using Jodatime, as I would like to use the base library only.)
Here is my test program:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class MidnightTester {
public static void runTestMidnight1() {
System.out.printf("runTestMidnight1() called\n");
TimeZone tz = TimeZone.getTimeZone("UTC");
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1437004800000L);
cal.setTimeZone(tz);
System.out.printf("Original timestamp:\n");
printCalendarWithTimeZone(cal, tz);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.printf("Timestamp after setting to midnight:\n");
printCalendarWithTimeZone(cal, tz);
}
public static void runTestMidnight2() {
System.out.printf("runTestMidnight2() called\n");
TimeZone tz = TimeZone.getTimeZone("UTC");
Calendar cal = Calendar.getInstance();
cal.setTimeZone(tz);
cal.setTimeInMillis(1437004800000L);
System.out.printf("Original timestamp:\n");
printCalendarWithTimeZone(cal, tz);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.printf("Timestamp after setting to midnight:\n");
printCalendarWithTimeZone(cal, tz);
}
public static void printCalendarWithTimeZone(Calendar cal, TimeZone tz) {
SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy, hh:mm:ss aaa");
sdf.setTimeZone(tz);
System.out.printf("%d= %s\n", cal.getTimeInMillis(), sdf.format(cal.getTime()));
}
public static void main(String argv[]) {
runTestMidnight1();
runTestMidnight2();
}
}
Here is the output:
runTestMidnight1() called
Original timestamp:
1437004800000= Thursday, July 16, 2015, 12:00:00 AM
Timestamp after setting to midnight:
1436918400000= Wednesday, July 15, 2015, 12:00:00 AM
runTestMidnight2() called
Original timestamp:
1437004800000= Thursday, July 16, 2015, 12:00:00 AM
Timestamp after setting to midnight:
1437004800000= Thursday, July 16, 2015, 12:00:00 AM
As you can see, in runTestMidnight1(), the day changes from July 16 to July 15 after setting the time to midnight! I don't get that.
What's more weird is that in runTestMidnight2(), I swap only two lines, and the day correctly stays the same on July 16.
cal.setTimeZone(tz);
cal.setTimeInMillis(1437004800000L);
I am in America/Pacific time, in case that matters.
Can someone help me understand what's going on?
EDIT: Better Explanation
When we call setTimeInMillis(), the passed long values is assumed to be in UTC. and it calculates the time in calendar object time using user's timezone or if any timezone already available with Calendar object.
If there is no timezone passed then user's timezone gets set on calendar object. So the value '1437004800000L' considered to be in PST timezone and time gets calculated with PST timezone.
Calling setTimeZone() after setting time in millis is changing the timezone in Calendar object. So the calendar object time gets moved to UTC. This is the case of runTestMidnight1(). And that's why we see a shift in date because original time was in PST.
While in second method, the timezone is first set by setTimeZone() to UTC. So the time value is '1437004800000L' and considered timezone is UTC and calculated time would be in UTC. And you gets UTC time only.
And this problem gets reproduced only if user is in timezone which behind the UTC timezone.
Hope it clarifies.

Get a Date instance for a day of week and time

I have a config file from where I am reading a day of week and a time of day in 24 hour format. A sample entry looks like this:
NextRun=Sunday|15:00:00
I will parse them out into day and time variables. However, I want to find the equivalent millisecond timestamp for the next Sunday 3:00pm.
So for example, if today is Sunday 4:00pm or Tuesday 1:00am it will be the next Sunday 3:00pm, but if it is Sunday 2:30pm now, the expected time will be 30 minutes from now.
Get a Calendar instance and set it with the parsed time and day. If it has passed, add a week.
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
c.set(Calendar.HOUR_OF_DAY, 15);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
if (c.getTimeInMillis() - Calendar.getInstance().getTimeInMillis() < 0)
c.add(Calendar.DAY_OF_YEAR, 7);
return c.getTimeInMillis();
Use GregorianCalendar which extends Calendar. try something like:
GregorianCalendar currentTime = new GregorianCalendar();
GregorianCalendar targetTime = new GregorianCalendar();
//Get Day and Time from config file
targetTime.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
//Add a week if the targetTime is from last Sunday
if (targetTime.before(currentTime))
{
targetTime.add(Calendar.DAY_OF_YEAR, 7);
}
System.out.println(currentTime.getTime().toString() + ", " + targetTime.getTime().toString());

How to check If the system Date is 30 days back

How to check in java whether the system Date is 30 days back
Means for example if today is May 26 then if i pass April 26 , it should tell that this is of Last Month Data
If(SystemDate-30)
http://joda-time.sourceforge.net/faq.html#datediff
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.add(Calendar.DATE, -30);
cal.set(HOUR, 0);
cal.set(MINUTE, 0);
cal.set(SECOND, 0);
cal.set(MILLISECOND, 0);
Date dateBefore30DayFromStartDate = cal.getDate();
Now you can compare

Reset time part of Calendar instance in Java

There is Java code,which is ran on 2 different environments and inserts records with JdbcTemplate to DB.
Results of its running are different for both envs. Particularly,for Date fields.
On first environment(Oracle XE) it produces record:
"12/03/2010";191094;"71697211000";3229;880323202;NULL;0;1;0;NULL;0;NULL
Second environment(Oracle non XE):
"12/03/2010 12:00:00";191094;"71697211000";3229;880323202;NULL;0;1;0;NULL;0;NULL
NLS_DATE_FORMAT(if it's crucial) for first env is DD-MON-RR,
for second env is DD-MON-RRRR
The question is,what Oracle settings may affect,that second env Date format is another?
should set following Calendar properties in Java code:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
instead of:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
According to the documentation, HH refers to a 12-hour time. The 12 in the time you're retrieving is 12 midnight. What you want is HH24, which ges you a 24-hour time, starting at 00 for midnight.
If you don't want to show the time part, don't include a format string which includes the time part ("HH:MI:SS").
You've reset the time part to midnight, basically... there's no way of differentiating between a Calendar or Date set to exactly midnight and a Calendar or Date "without" a time part - because there's no such concept as a Calendar/Date with only a date part.
Now you may be able to have that in the database, depending on what types are available to you - but java.util.Date and java.util.Calendar always represent points in time, not just dates.
The reason it's showing 12 instead of 00 is because you're using "HH" instead of "HH24", as per lacqui's answer. I assume you don't really want to see the time at all though, given that you'll have reset it to midnight...
I'd recommend you extend one of the Calendar classes like this:
public class CalendarDateOnly extends GregorianCalendar {
public static Calendar getInstance() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
return cal;
}
}
Instantiate in this way:
Calendar june30 = CalendarDateOnly.getInstance();
june30.set(2000, Calendar.JUNE, 30);
/*
* Date : 2015-07-09
* Author : Bhuwan Prasad Upadhyay
*/
package com.developerbhuwan.date.utils;
import java.util.Calendar;
import java.util.Date;
/**
*
* #author developerbhuwan
*/
public class CalenderUtils {
public static Calendar getNewCalendarInstance() {
Calendar calendar = Calendar.getInstance();
return resetCalender(calendar);
}
public static Date resetDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return resetCalender(calendar).getTime();
}
public static Calendar resetCalender(Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
public static void setTimeInCalendar(Calendar calendar, Date date) {
calendar.setTime(resetDate(date));
}
}

Categories