this is my code
TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
Timestamp start = new Timestamp(calendar.getTime().getTime());
but the timestamp result is for instance = 2014-09-30 02:00:00.0 I´m not able to set the hours to 0.
Any suggestions.
Once you call Calendar.getTime() you get a Date object which is an instant in time which has no timezone info.
When you want to print or present this instance, the formatter will use the default time zone if not explicitly specified, which in your case is not UTC but maybe CET.
When you convert this instant to a String, you also have to tell in which timezone you want it to present. You have to specify UTC timezone there as well.
For example if using SimpleDateFormat, you can use its setTimeZone() method.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(start));
Also if your result is from your database, you have to use a timestamp SQL type without timezone or with the UTC timezone.
I guest icza is right.
To be sure, try this :
Timestamp start = new Timestamp(calendar.getTime().getTime());
System.out.println(start.getTimezoneOffset());
Related
Is there any way to use the following simpleDateFormat:
final SimpleDateFormat simpleDateFormatHour = new SimpleDateFormat("HH:mm:ss z");
and when invoking:
simpleDateFormat.parse("12:32:21 JST");
to return current date on the Date object?
For these example, it will return:
Thu Jan 01 05:32:21 EET 1970
and not:
<<today>> 05:32:21 EET <<currentYear>>
as I need.
No, SimpleDateFormat needs explicity the date in the input string. If you're using Java 8, you can go with a LocalDateTime:
LocalDateTime localDateTime = LocalDate.now().atTime(5, 32, 21);
If you want to include a time-zone, you can use ZonedDateTime.
Construct another SimpleDateFormat to print today's date:
String today = new SimpleDateFormat("yyyy/MM/dd").print(new Date());
(Be careful here: you might want to set the time zone on the SimpleDateFormat, as "today" is different in different time zones).
Update the date format to include year, month and day:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z");
And then prepend the date string with the date you want:
simpleDateFormat.parse(today + " " + "12:32:21 JST");
A better solution using flexible default values (today instead of 1970-01-01) would be in Java-8 with the new built-in date-time-library located in package java.time:
String input = "12:32:21 JST";
String pattern = "HH:mm:ss z";
LocalDate today = LocalDate.now(ZoneId.of("Asia/Tokyo"));
DateTimeFormatter dtf =
new DateTimeFormatterBuilder().parseDefaulting(ChronoField.YEAR, today.getYear())
.parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue()).parseDefaulting(
ChronoField.DAY_OF_MONTH,
today.getDayOfMonth()
).appendPattern(pattern).toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(input, dtf);
System.out.println(zdt); // 2016-12-23T12:32:21+09:00[Asia/Tokyo]
However, I still see a small bug related to the fact that this code makes a hardwired assumption about the used zone BEFORE parsing the real zone so please handle with care. Keep in mind that the current date depends on the zone. But maybe you only need to handle a scenario where just the Japan time is used by users.
Hint: You can also parse in two steps. First step with any kind of fixed default date in order to get the zone information of the text to be parsed. And then you can use this zone information for suggested solution above. An awkward but safe procedure.
You can use this code if you want to change only the year and the day
final SimpleDateFormat simpleDateFormatHour = new SimpleDateFormat("HH:mm:ss z");
Date date = simpleDateFormatHour.parse("12:32:21 JST");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
calendar.set(Calendar.DAY_OF_YEAR, Calendar.getInstance().get(Calendar.DAY_OF_YEAR));
date = calendar.getTime();
I get a string in the format yyyy-MM-dd HH:mm which represents a Date and Time in UTC.
Next step is to put this into a Calendar (with TimeZone UTC).
In addition need to also create a separate Calendar which has converted the UTC to "Europe/London" timeZone (GMT/BST).
After that I need to be able to detect if the "Europe/London" calendar has a DST (Day Light Savings Offset).
The code below will show you how far I have got and it runs ok on a UK based computer whose default System Timezone is GMT. However when I run it on a pc whose timezone is UTC it fails. It seems to not be able to tell me if there is an DST_offset (its always zero).
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(Calendar.YEAR, 2016);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 27);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 35);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//This is required as Java Date JAN starts at 0.
int MonthCon = cal.get(Calendar.MONTH)-1;
cal.set(Calendar.MONTH, MonthCon);
Date d = cal.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC: " + f.format(d));
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println("BST: " + f.format(d));
//Creates a BST calendar of the same UTC time
String dateStrBST = f.format(d);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrBST);
System.out.println("BSTNewDate: " + f.format(dateObjBST));
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("BST"));
calBST.setTime(dateObjBST);
System.out.println("Current TimeZone is : " + calBST.getTimeZone());
int offset = calBST.get(Calendar.DST_OFFSET);
System.out.println("Day Light Savings: "+offset);
System.out.println("Transition Day: "+isDSTTransitionDay(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH))+" Transition Type: "+DSTtransitionType(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)));
Unfortunately I need to be able to detect if any particular day is a transition day, that is to say a day that changes from DST on/off or off/on. Again this works on the local computer but not on the UTC timezone one.
private static boolean isDSTTransitionDay(int year, int month, int day) throws ParseException
{
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, year);
calStartofDay.set(Calendar.MONTH, month);
calStartofDay.set(Calendar.DAY_OF_MONTH, day);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Date dStartofDay = calStartofDay.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
String dateStrUTCtoBST = f.format(dStartofDay);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrUTCtoBST);
Calendar calBST = Calendar.getInstance();
calBST.setTime(dateObjBST);
int offsetStart = calBST.get(Calendar.DST_OFFSET);
calBST.add(Calendar.HOUR_OF_DAY, 23);
int offsetEnd = calBST.get(Calendar.DST_OFFSET);
//System.out.println("Start: "+offsetStart+" End: "+offsetEnd);
if (offsetEnd == offsetStart)
{
return false;
}else
{
//if(offsetStart<offsetEnd) {System.out.println("Transition to BST");}else{System.out.println("Transition to UTC/GMT");};
return true;
}
}
So on the UTC computer it fails miserably as it always puts Calendar.DST_OFFSET at zero. I have clearly misunderstood something along the way so any help/clarity would be good.
I pretty much have to keep Calendars as the rest of the code uses it but I realise the Java8 has many more fancy ways to do things.
Please allow me to be honest, I tried to read your code and didn’t really understand your way of trying to obtain what you want. If you can use Java 8, I recommend switching to using the Java 8 date and time classes. With these your job isn’t very complicated. For the demonstration I have chosen last October 30, the date when Britain (and EU) changed back from summer time (daylight saving time) to standard time.
String originalDate = "2016-10-30 23:35";
LocalDateTime localTime = LocalDateTime.parse(originalDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
ZonedDateTime utcTime = localTime.atZone(ZoneOffset.UTC);
ZonedDateTime bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
// the summer time offset is how many milliseconds?
long dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
// try the same at start of day (midnight)
utcTime = utcTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 3600000
// and next midnight
utcTime = utcTime.plusDays(1);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
You are using
Calendar calBST = Calendar.getInstance();
That sets calBST to the computer's timezone (on the UTC computer, it will be UTC).
calBST.setTime(dateObjBST); sets the time, not the timezone.
Try using getInstance(TimeZone zone) there also.
In any case, I would replace your code like this:
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, 2017);
calStartofDay.set(Calendar.MONTH, 0);
calStartofDay.set(Calendar.DAY_OF_MONTH, 21);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
calBST.setTimeInMillis(calStartofDay.getTimeInMillis());
// use this to check the time
System.out.printf("%tc%n", calBST);
Also, from the Calendar docs, be careful about this:
set(f, value) changes calendar field f to value. In addition, it sets
an internal member variable to indicate that calendar field f has been
changed. Although calendar field f is changed immediately, the
calendar's time value in milliseconds is not recomputed until the next
call to get(), getTime(), getTimeInMillis(), add(), or roll() is made.
Thus, multiple calls to set() do not trigger multiple, unnecessary
computations. As a result of changing a calendar field using set(),
other calendar fields may also change, depending on the calendar
field, the calendar field value, and the calendar system. In addition,
get(f) will not necessarily return value set by the call to the set
method after the calendar fields have been recomputed. The specifics
are determined by the concrete calendar class.
With the following code-
Timestamp ts = (Timestamp)results.get(0);
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z");
System.out.println(sdf.format(new Date(ts.getTime())));
I get output as: 04/29/2013 15:08:30 +0530
I wanted to create a TimeZone instance from the timestamp, so tried this-
SimpleDateFormat FORMATTER = new SimpleDateFormat("Z");
String tzString = FORMATTER.format(ts);
// the tzString comes out to be +0530 (which is correct)
TimeZone tz = TimeZone.getTimeZone(tzString);
System.out.println(tz);
But the final TimeZone instance is of GMT as its not able to identify +0530.
So, how can I get a correct TimeZone instance here?
You cannot get a TimeZone from a java.sql.Timestamp because it does not contain one. In your case you are simply getting your default TimeZone. It does not make sense. It is the same as TimeZone.getDefault();
Use a lowercase z in your pattern. That should return "GMT+0530", which will work.
Instead of using a SimpleDateFormat, you can simply do this:-
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(ts.getTime()));
TimeZone tz = cal.getTimeZone();
System.out.println(tz);
I tried this code below:
Timestamp ts = new Timestamp(System.currentTimeMillis());
Then to get the TimeZone instance from the timestamp, I did this:
SimpleDateFormat FORMATTER = new SimpleDateFormat("Z");
TimeZone tzone = FORMATTER.getTimeZone();
System.out.println(tzone.getDisplayName());
System.out.println(tzone.getID());
I got:
Central European Time
Europe/Berlin
So I got my timezone which is +0200 instead of GMT.
Hope this is what you want.
Turkey has two TimeZone GMT+2 and GMT+3.
I want to change the GMT+2 dates into GMT+3, but I want to protect hours and minutes that in GMT+2 TimeZone.
I want to take hours and minutes, and then set these values into GMT+3 TimeZone date. At result there must be no change in hours and minutes but the timeZone must be change only. At function toconvert date is must be GMT+2 format, but the return value must be GMT+3 format. How to do it clearly?
public static Date convertTimezone(Date toConvert) {
Date date = new Date();
date.setYear(toConvert.getYear());
date.setMonth(toConvert.getMonth());
date.setHours(toConvert.getHours());
date.setMinutes(toConvert.getMinutes());
return date;
}
In Java a Date represents a point in time, nothing else. This means that Date knows nothing about how it is printed, which time zone etc...
Time Zone is therefore something you set when printing the Date. The class DateFormat is typically used for printing and the time zone is part of the properties you can set on DateFormat. Typically, people use the subclass SimpleDateFormat.
java.util.Date cannot track your Timezone details. Use Calendar instead
You shouldn't use a Date object in this case. Use Calendar instead.
public static Calendar convertTimezone(Calendar toConvert) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+3"));
calendar.set(Calendar.YEAR, toConvert.get(Calendar.YEAR));
calendar.set(Calendar.MONTH, toConvert.get(Calendar.MONTH));
calendar.set(Calendar.DATE, toConvert.get(Calendar.DATE));
calendar.set(Calendar.HOUR_OF_DAY, toConvert.get(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE, toConvert.get(Calendar.MINUTE));
return calendar;
}
You can make use of Calender API to convert one timezone to other
public static Date convertTimezone(Date toConvert) {
Calender calendar = Calendar.getInstance();
calender.setTime(toConvert);
int hour = calender.get(Calender.HOUR_OF_DAY);
int minutes = calender.get(Calender.MINUTE);
Calendar ret = new GregorianCalender(timeZone); //timeZone is destination TimeZone
ret.setTimeInMillis(calendar.getTimeInMillis() +
timeZone.getOffset(calendar.getTimeInMillis()) -
TimeZone.getDefault().getOffset(calendar.getTimeInMillis()));
ret.set(Calender.HOUR_OD_DAY, hour);
ret.set(Calender.MINUTE, minutes);
return ret.getTime();
}
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("PST"));
cal.setTime(new Date());
System.out.println("cal:"+cal);
System.out.println("cal.getime:"+cal.getTime());
output are:
cal:java.util.GregorianCalendar[time=1325177592164,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="PST",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=PST,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2011,MONTH=11,WEEK_OF_YEAR=53,WEEK_OF_MONTH=5,DAY_OF_MONTH=29,DAY_OF_YEAR=363,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=8,HOUR_OF_DAY=8,MINUTE=53,SECOND=12,MILLISECOND=164,ZONE_OFFSET=-28800000,DST_OFFSET=0]
cal.getime:Thu Dec 29 22:23:12 IST 2011
Problems facing:
While print 'cal' object getting date and time as per time zone.
cal.getTime() not displaying date and time to as per timezone.
You should represent time in UTC (java.util.Date) and then display the time in the local timezone of the user. Use DateFormat and TimeZone to do that. Read this article for more details
Unfortunately Date object always display time in GMT. You need to use something like SimpleDateFormat to display time in formatted timezone.
assign user given time into string variable then create date formatter. then parse the given string using date formatter.
String dateAndTime = "30-12-2011 12:00:00 GMT+5.30"; dateFormate
formate = new SimpleDateFormate("dd-mm-yyyy hh:mm:ss z"); Date date =
formate.parse(dateAndTime );
Date object is Java doesn't store the TimeZone info.
If you do
new Date()
this is the current local time of the machine/jvm.
To print it with the default/local timezone info:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
System.out.println(sdf.format(new Date()));