Java-Adding timezone to date when date is grabbed from datepicker - java

I have a jsp page that takes the value from a jquery datapicker and passes it into a search. The user of the site has the opportunity to change their timezone to fit where they are located in the world. I want to take the value searched which is based off the browsers time and format it and show it on screen with the user’s timezone.
The column is expireDate and I use datatables to display the results.
{
"mData":"expireDate",
"mRender":function(source,type,full){
if(-1==source)
return "";
var toDate = new Date(source);
var stringDate = toDate.toString(dateTableFormater);
return stringDate;
I get the value and pass in my own custom formatting, the formatting is based on where the person lives. Each format is different depending on where they live and prevents me from using the simpledateFormat.setTimezoneOffset();
$("#expireFrom").datepicker($.datepicker.regional[plannerLang]);
$("#expireFrom").datepicker( "option", "dateFormat",dateFormater);
$("#expireTo").datepicker($.datepicker.regional[plannerLang]);
$("#expireTo").datepicker( "option", "dateFormat",dateFormater);
I have a dto set up so it gets the users Timezone, I just cant figure out how to implemet that so when the time is sent back to the jsp the timezone has been included in the time.
How do you add/subtract the timezone difference from the date that the browser has gotten?

Adjust for Time Zone Offset
Computers track time in a universal manner, free of time zone information. They use a count of seconds/milliseconds/nanoseconds since an epoch. So adjusting for time zone is not a matter of adding or subtracting to the time itself. It's a matter of adjusting the expression of that time/count as a string.
Joda-Time
The bundled java.util.Date/Calendar classes are notoriously bad in both design and implementation. You should use a competent date-time library instead. Currently, that means Joda-Time. In the future, with Java 8, you can continue with Joda-Time or switch to the new bundled java.time.* classes defined by JSR 310. Those classes are inspired by Joda-Time but are entirely re-architected.
A DateTime instance in Joda-Time knows its own time zone, unlike a java.util.Date.
Server Time
Most programmers find it wiser to use the server's clock rather that obtain time from the user’s machine. Users’ machines are notorious for being out of sync with the correct time. That is less true today with the Internet and NTP servers. Nevertheless, I suggest you stick with server’s clock.
From the user’s machine you should obtain their Locale information, country (culture) and language.
By the way, usually best to work in UTC (no time zone offset) in your business logic and switch to a time zone only for presentation to user.
Example Code For Time Zone
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Athens" );
DateTime now_Athens = new DateTime( timeZone );
DateTime now_Seattle = now_Athens.toDateTime( DateTimeZone.forID( "America/Los_Angeles" ));
DateTime now_UTC = now_Athens.toDateTime( DateTimeZone.UTC );
Dump to console…
System.out.println( "now_Athens: " + now_Athens );
System.out.println( "now_Seattle: " + now_Seattle );
System.out.println( "now_UTC: " + now_UTC );
When run…
now_Athens: 2014-01-02T20:11:43.657+02:00
now_Seattle: 2014-01-02T10:11:43.657-08:00
now_UTC: 2014-01-02T18:11:43.657Z
Formatting Strings
Joda-Time has many features for rendering strings via formatting:
You can format with Locale-sensitive Long, Medium, Short formatters.
You can define your own formats.
You can go with standard ISO 8601 formats, the default, as seen above.
Example Code For Formatting
DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" );
String nowLocalizedParis = DateTimeFormat.forStyle("LS").withLocale(Locale.FRANCE).withZone( timeZone_Paris ).print( now_UTC );
Dump to console…
System.out.println( "nowLocalizedParis: " + nowLocalizedParis );
When run…
nowLocalizedParis: 2 janvier 2014 19:11

Related

How to show the correct timezone to users?

I have a Java SE server application with a Saas website and registered users.
I have many events that occur on my server in different days.
Time is registered in localhost in a long number via SYSTEM.currentTimeMillis()/1000
Registered users can check these events time from their respective country and they need to see the correct time based on their timezone (not server timezone) through the website.
How do I show them the historical time of the events in their timezone?
Any idea about how you would deal with this situation?
Easiest way is to use http://momentjs.com/timezone/. Idea is following - you send sth like this in html markup
<div class="raw-datetime">2014-12-01 12:00:00 UTC+03:00</div>
And after page loads - you run javascript that adjusts all raw datetime to browser timezone.
java.time
First you need to determine the user’s time zone. Search on StackOverflow to learn that ultimately the best way to do that is to ask the user. You can try to use JavaScript on the browser to auto-detect a time zone, but there are issues.
You need to arrive at a proper time zone name, usually a continent/cityOrRegion such as America/Montreal or Asia/Kolkata. Never use those 3-4 letter codes like EST or IST as they are neither standardized nor unique.
To localize a date-time you need to know the user’s Locale, a human language and a set of cultural norms.
With a time zone in hand, use the new java.time framework built into Java 8 and later. Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project.
long epochSeconds = … ;
Instant instant = Instant.ofEpochSeconds( epochSeconds );
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant, zoneId);
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale );
String output = zdt.format( formatter );
First of all, we will use UTC as a default and unique time zone in the system. Because, the time never go back or go to the future in UTC. There is no time shift for daylight saving.
So, all applications (applications which we develop and has timezone support for their users) environment require a JVM parameter, which provides a UTC based environment.
Timezone JVM parameter usage
-Duser.timezone=UTC
For Views
For views, the date/time object should be rendered according to the specified time-zone. For Java world, this is handled by formatDate tld in jstl.
Every project contains its own timezone holding logic itself.
User.timeZone : for admin panels
Some fmt:formatDate example
<fmt:formatDate value="${someDateTime}" timeZone="${user.timeZone}" pattern="MMM dd, yyyy - HH:mm:ss.S"/>
For further information about formatDate taglib please see check the link or google it.
For Forms (Getting the date / time data from the user)
When you getting date information via forms the you need to consider time zone and perform the time conversion. The conversion direction is User Time zone to UTC.
The time in database should be in UTC time zone.
Motto is save it globally; show it locally :)
EDIT:
Hold timezone as a subfield of User object and set it to your formatter when you want to show the time, you can use it in JavaSE.
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
formatter.setTimeZone(TimeZone.getTimeZone(user.getTimeZone()));

Date gives one day less than actual date while converting from date to calendar

I am passing date from front end which is IST(date of indian timezone). And in java code i am converting date to calendar using the following code(This is happening in the server which is there in US PST timezone).
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;
so when i see the last log the day of the month will be one day less than what i passed.eg. if i pass 22/06/2015 IST it shifts to 21/06/2015. so after processing finally it displays 21/06/2015 in the list of data which is in another UI page.
This happens because JVM on server side and JVM on client side use different time zones by default Java TimeZone:
Typically, you get a TimeZone using getDefault which creates a
TimeZone based on the time zone where the program is running. For
example, for a program running in Japan, getDefault creates a TimeZone
object based on Japanese Standard Time.
As we can see, Pacific Time Zone on server has UTC−8:00 and Indian Standard Time on client has UTC+05:30. They differ by 13.30 and Indian date X converts to US as X-13.30 what may yield a day before on server side for certain X.
Several workarounds are possible depending on how you can influence/modify your server and client application. For example, you may work with dates in UTC+00:00 time zone on both server and client sides. If you need to show a date to the user you may convert it to Indian time zone when needed.
// Set default GMT+0:00 time zone
TimeZone timeZone;
timeZone = TimeZone.getTimeZone("GMT+0:00");
TimeZone.setDefault(timeZone);
Instead of simply using Calendar cal = Calendar.getInstance(); you may create "clear" calendar which you will user later on to set day, month and year
public static Calendar createClearedCalendar() {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(timeZone);
cal.set(1970, 0, 1, 0, 0, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MILLISECOND);
return cal;
}
By the way, if you manipulate date-time in Java you may consider Joda Time which has more extended options and optimized performance.
The Answer by Antonio is correct and should be accepted (click the big empty check mark).
This Answer adds some thoughts and example code.
Avoid 3-Letter Time Zone Codes
Avoid using, or even thinking about, those 3 or 4 letter codes such as IST or PST. They are not standardized, they are not unique, and they further confuse issues around Daylight Saving Time (DST). For example, IST means "India Standard Time", "Irish Standard Time", and more.
Use proper time zone names. Most of these are in a "continent" + "/" + "city/region" pattern. The city/region name is not meant specifically for that town, but rather as an easily identifiable name for as wide an area as possible that shares the same set of past, present, and future rules for time zone rules and anomalies (including DST).
Use UTC
Generally you should be using UTC time zone for all your business logic, data storage, and data exchange. Adjust to a particular time zone only for presentation when expected by the user.
Use A Decent Date-Time Framework
The old java.util.Date/.Calendar classes were a bold attempt at handling date-time work, but ultimately they failed. They are notoriously troublesome, flawed in both design and implementation. Avoid them.
The 3rd-party Joda-Time library is one solution. It works in many versions of Java and also in Android. Joda-Time inspired the other solution, the java.time package found in Java 8 and later (Tutorial).
Solution
The Question seems to have a goal of taking a java.util.Date object, assign desired time zone, and produce a java.util.Calendar object.
Fortunately the java.time framework has conversion methods. See this Tutorial page.
Example code follows, using java.time from Java 8 Update 45.
You may want imports such as:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
Let's simulate getting a java.util.Date passed in. We'll instantiate a Date based on "now".
Date inputDate = new Date( ); // Simulate getting a java.util.Date object.
Then we define the desired time zones, using proper time zone names. Let’s throw in Montréal just for fun as well as the pacific United States and India time zones mentioned in the Question.
ZoneId zoneLosAngeles = ZoneId.of( "America/Los_Angeles" );
ZoneId zoneMontréal = ZoneId.of( "America/Montreal" );
ZoneId zoneKolkata = ZoneId.of( "Asia/Kolkata" );
Then we convert that to an Instant, a point on the timeline without regard to time zone.
Instant instant = inputDate.toInstant( );
Then we assign various time zones to create ZonedDateTime instances. See how we can instantiate a ZonedDateTime in either of two ways: [a] from an Instant, or [b] from another ZonedDateTime via the withZoneSameInstant method. Both ways are shown below.
Note that java.time (and Joda-Time) uses immutable objects, a design pattern where we create new instances based on the old instance rather than alter ("mutate") the old instance. Thread-safety is one of the major benefits.
ZonedDateTime zdtLosAngeles = ZonedDateTime.ofInstant( instant, zoneLosAngeles );
ZonedDateTime zdtMontréal = ZonedDateTime.ofInstant( instant, zoneMontréal );
ZonedDateTime zdtKolkata = ZonedDateTime.ofInstant( instant, zoneKolkata );
ZonedDateTime zdtUtc = zdtKolkata.withZoneSameInstant( ZoneOffset.UTC );
Lastly, we convert one of those to a GregorianCalendar object which is a subclass of java.util.Calendar.
GregorianCalendar calendarKolkata = GregorianCalendar.from( zdtKolkata );
Dump to console.
System.out.println( "inputDate: " + inputDate );
System.out.println( "zdtLosAngeles: " + zdtLosAngeles );
System.out.println( "zdtMontréal: " + zdtMontréal );
System.out.println( "zdtKolkata: " + zdtKolkata );
System.out.println( "zdtUtc: " + zdtUtc );
System.out.println( "calendarKolkata: " + calendarKolkata );
When run.
inputDate: Wed Jun 24 15:12:12 PDT 2015
zdtLosAngeles: 2015-06-24T15:12:12.153-07:00[America/Los_Angeles]
zdtMontréal: 2015-06-24T18:12:12.153-04:00[America/Montreal]
zdtKolkata: 2015-06-25T03:42:12.153+05:30[Asia/Kolkata]
zdtUtc: 2015-06-24T22:12:12.153Z
calendarKolkata: java.util.GregorianCalendar[time=1435183932153,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Kolkata",offset=19800000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2015,MONTH=5,WEEK_OF_YEAR=26,WEEK_OF_MONTH=4,DAY_OF_MONTH=25,DAY_OF_YEAR=176,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=3,HOUR_OF_DAY=3,MINUTE=42,SECOND=12,MILLISECOND=153,ZONE_OFFSET=19800000,DST_OFFSET=0]

Whats the most efficient way to persist a Joda-Time `DateTime` object?

I've written some Java software that very frequently persists and retrieves Joda-Time DateTime objects from Redis. I just serialise and deserialise the objects at present. The software reads the objects about 50 times more often than it writes. I've not profiled serialising/deserialising Joda-Time objects, but the software has scaled well, computationally, under load and I'm happy with the performance.
What hasn't scaled well is memory usage. The serialised Joda-Time objects are pretty big and a decent size Redis instance can only take about 3 days worth of customer data before I need to flush it out to a relational database on disk. A secondary issue is Redis' own backup mechanisms seem harder to manage the larger the dataset gets...
Setting aside the temptation to throw more RAM at the problem, I've thought of the following ideas so far:
serialise then compress the objects before persisting
persist as a ISO date format string
persist as some other Joda-compatible string format
I will try out and profile these before deciding, but I wonder if anyone can think of a more efficient way of reducing the memory footprint of persisted Joda objects without breaking the computational bank?
ISO 8601
While I know nothing of Redis… Generally speaking, the easiest and most efficient way to serialize Joda-Time objects is to take advantage of their built-in support for the sensible, unambiguous, standard ISO 8601 string formats for date-time values.
For a zoned date-time value, the standard provides a YYYY-MM-DDTHH:MM:SS.SSS±HH:SS format such as 2014-10-24T21:17:30+02:00 or 2014-10-24T19:17:30Z (Z for Zulu means an offset of 00:00 from UTC).
The various Joda-Time 2.5 classes use ISO 8601 as their defaults for parsing and generating String representations of date-time values.
Generating Strings
For DateTime, simply call its toString method either explicitly or implicitly.
String output = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).toString();
Generally best to work with UTC when storing date-time values. Joda-Time lets you easily adjust to UTC.
DateTime nowMontreal = DateTime.now( DateTimeZone.forID( "America/Montreal" ) );
DateTime nowUtc = nowMontreal.withZone( DateTimeZone.UTC );
String output = nowUtc.toString();
Another example.
DateTime output = DateTime.now( DateTimeZone.UTC ).toString();
Parsing Strings
Parsing is just as easy. The only issue is time zone. If you omit a time zone, generally Joda-Time will assign the JVM’s current default time zone. Usually better if you explicitly specify the desired time zone.
DateTime dateTimeMontreal = new DateTime( "2014-10-24T19:17:30Z", DateTimeZone.forID( "America/Montreal" ) );
or, for UTC…
DateTime dateTimeUtc = new DateTime( "2014-10-24T19:17:30Z", DateTimeZone.UTC ) );
java.time
Another alternative is the new java.time package built into Java 8. Inspired by Joda-Time, java.time is similar in many ways. But one difference is that java.time by default generates string representations by extending the ISO 8601 standard to append the name of the time zone. While standard format has an offset-from-UTC, you loose the actual time zone information. (A time zone is an offset plus the rules for Daylight Saving Time and other anomalies in the present, future, and past.)
On the other hand, generally it is best to store date-time in UTC. If you really care about the time zone at the time of data-entry, it’s generally best to store that information separately in addition to the UTC-adjusted value.
In java.time, the Instant class represents a moment on the timeline in UTC.
Instant instant = Instant.parse( "2014-10-24T19:17:30Z" );
String outputInstant = instant.toString();
2014-10-24T19:17:30Z
To adjust into a time zone, specify a ZoneId to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
String outputZdt = zdt.toString();
2014-10-24T15:17:30-04:00[America/Montreal]
Try to analyze a distribution of your date-time objects. If it happens that they are relatively close to each other, then you can do some "magic":
1) you can introduce a special "starting point date" constant and then store the actual date as a number of days shift from the constant - that would be integer value (~8 bytes on 64bit arch. w/o compression)
2) do you need actual time? if no - just throw away time; if yes - you can store hours+minutes+seconds in one int variable (another ~8 bytes on 64bit arch. w/o compression)
3) analyze results - there is a chance that you could fit both: the date (shift) and the time in a single int variable
4) introduce a caching mechanism, that would greatly increase performance of serializing/deserializing your objects
Store the millis since the start of the epoch. It is a single long value. If you need a timezoned value also store timezone Id as a string. Serializing and parsing the string representation will always take more resources including RAM, there so much data processing inside, some regex, split calls which allocates more memory.
Use this constructor for restoring the value: public BaseDateTime(long instant, DateTimeZone zone)
It is so light waight because it is stores rightaway what is under the hood of every DateTime instance:
public BaseDateTime(long instant, Chronology chronology) {
super();
iChronology = checkChronology(chronology);
iMillis = checkInstant(instant, iChronology);
adjustForMinMax();
}

Compensating for BST when calculating difference between 2 times

I need some help or a pointer in the right direction.
I am trying to get the difference between 2 times. I am in UK on GMT with timezone set to adjust for daylight saving automatically.
When I preform the following it is always 1 hour out unless, I switch off automatically adjust for daylight saving.
String strDate = new java.text.SimpleDateFormat("HH:mm:ss").format(new Date().getTime() - oldDate.getTime());
If I run the following there is not the 1 hour difference the 2.
System.out.println("Current time " + Formats.HOURMIN.formatValue(new Date().getTime()));
System.out.println("Old time " + Formats.HOURMIN.formatValue(oldDate.getTime()));
Any assistance would be appreciated.
The cardinal rule for calculating time intervals when different timezones are involved is to make sure to convert the times to UTC before subtracting.
Each time, no matter what zone and DST offset is in effect at the time (pun somewhat intended), converts to a unique UTC instant. Once you have the times in UTC, calculating the difference is a simple subtraction. The result is time-zone-independent.
The java.util.Date class has no time zone attached to it yet confusingly uses your default time zone when rendering a string. I'm guessing this may be your problem. One of many reasons to avoid java.util.Date/Calendar classes.
The Joda-Time 2.3 library makes this kind of work easier. Look at the Period, Duration, and Interval classes.
In contrast to a java.util.Date, in Joda-Time a DateTime instance does indeed know its assigned time zone.
The ISO 8601 standard defines a way to describe durations as hours, minutes, and such in a PnYnMnDTnHnMnS format. I use that in my example code below. Joda-Time offers other ways as well.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTimeZone timeZone = DateTimeZone.forID( "Europe/London" );
DateTime dateTimeNew = new DateTime( timeZone );
DateTime dateTimeOld = dateTimeNew.minusHours( 2 );
Period period = new Period( dateTimeOld, dateTimeNew );
Dump to console…
System.out.println( "dateTimeNew: " + dateTimeNew );
System.out.println( "dateTimeOld: " + dateTimeOld );
System.out.println( "period: " + period );
When run…
dateTimeNew: 2014-01-02T23:19:45.021Z
dateTimeOld: 2014-01-02T21:19:45.021Z
period: PT2H

Daylight saving time in java

please see if you can tell me how to handle the DST issue in my case.
first, my application is a logistic system and it is for global user,so it involves timezone problem,i will handle it as following when set user local date of booking:
1.when user login application,we could get user's timezone according to login IP,but is is just an offset (i don't remember the term of this stuff) e.g "GMT+08"(BeiJing) or "GMT-06"(Chicago) .
2.before user save booking ,we need to set booking local date,as i can't get user local date direct .so i will get the server date first(in my case,it is BeiJing time),then calculate local date according to server date and user timezone,e.g if user timezone is "GMT-08",server date is 2013-08-29 17:45:00. server timezone is "GMT+08",then i will use server date-8-8 and the result will be 2013-08-29 01:45:00.but as i don't consider the DST,the calculated local date will be difference from the actual date.e.g now in San Francisco,the actual local date will be earlier one hour than the result that i calculated using this way,
i find the java TimeZone have already considered the DST problem,but i need to provide "location" name(e.g US/Alaska,Pacific/Apia) when construct TimeZone . while in my case, what i can get is just the offset.so can you tell me how to fix the DST issue in my case?
Yes, you should use either Joda-Time or the new java.time package in Java 8 (inspired by Joda-Time).
An offset is the number hours-minutes-seconds from UTC (GMT) that is represented by a certain date-time value. West coast is -08:00 (ignoring Daylight Saving Time nonsense), meaning 8 hours behind UTC.
Beware that java.time in its initial release has a small bug where it fails to handle an offset of just hours (such as +08) without minutes (such as +08:00).
A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region.
Use proper time zone names (mostly continent slash city). Avoid the 3 or 4 letter codes, such as EST, which are neither standardized nor unique.
A java.util.Date has no time zone, while a Joda-Time DateTime does.
To get a web browser's time zone, see this question. But often, this does not work well. As you've probably seen, many web sites ask the user to choose a time zone.
Your exact use-case is confusing. Generally the best approach is to use date-time values for UTC, then adjust to user's local time as needed. Usually best for your software to work and store date-times as UTC. Then present a local date-time adjusted to suit the user. In other words, think globally (UTC), present locally (local time zone adjusted).
Usually sysadmins keep their server computers set to UTC (no time zone offset). If your OS (like Mac OS X) does not offer UTC, then use Reykjavik as Iceland uses UTC year-round without any Daylight Saving Time. Likewise, database engines almost always convert date-time values to UTC for storage.
Joda-Time does offer a LocalDate class for when you truly do not care about time zone or time. But often it is better to use a date-time (a DateTime instance), and format for a date-only string as needed.
Example code in Joda-Time 2.3.
DateTimeZone timeZoneChina = DateTimeZone.forID( "Asia/Shanghai" );
DateTime dateTimeChina = new DateTime( 2013, 8, 29, 17, 45, 00, timeZoneChina );
DateTime dateTimeUtc = dateTimeChina.withZone( DateTimeZone.UTC );
DateTime dateTimeParis = dateTimeChina.withZone( DateTimeZone.forID( "Europe/Paris" ) );
DateTimeZone timeZoneUsWestCoast = DateTimeZone.forID( "America/Los_Angeles" );
DateTime dateTimeUnitedStatesWestCoast = dateTimeChina.withZone( timeZoneUsWestCoast );
DateTimeFormatter formatter = ISODateTimeFormat.date();
String outputDateOnlyForUnitedStatesWestCoast = formatter.withZone( timeZoneUsWestCoast ).print( dateTimeUtc );
Dump to console…
System.out.println( "dateTimeChina: " + dateTimeChina );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUnitedStatesWestCoast: " + dateTimeUnitedStatesWestCoast );
System.out.println( "outputDateOnlyForUnitedStatesWestCoast: " + outputDateOnlyForUnitedStatesWestCoast );
When run…
dateTimeChina: 2013-08-29T17:45:00.000+08:00
dateTimeUtc: 2013-08-29T09:45:00.000Z
dateTimeParis: 2013-08-29T11:45:00.000+02:00
dateTimeUnitedStatesWestCoast: 2013-08-29T02:45:00.000-07:00
outputDateOnlyForUnitedStatesWestCoast: 2013-08-29
java.time
Similar code in java.time.
Current moment in UTC.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
Adjust into a time zone for Chicago area, yielding a ZonedDateTime object.
ZoneId zChicago = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdtChicago = instant.atZone( z ) ;
Adjust into China time zone.
ZoneId zShanghai = ZoneId.of( "Asia/Shanghai" ) ;
ZonedDateTime zdtShanghai = zdtChicago.withZoneSameInstant( zChicago ) ;
All three objects (instant, zdtChicago, and zdtShanghai) represent the same moment, the same point on the timeline. Simultaneous, but seen through various wall-clock times.
Apparently you want just the date portion for some purpose, without the time-of-day and without time zone. For that extract a LocalDate object.
LocalDate ld = zdtChicago.toLocalDate() ;
Of course that may be a different date than returned by zdtShanghai.toLocalDate().
You may need to construct a specific moment.
ZonedDateTime zdtShanghai = ZonedDateTime.of( 2013, 8, 29, 17, 45, 0, 0 , zShanghai ) ;
Location and time zone
You said:
i need to provide "location" name
Location has nothing to do with time zone. A businessperson from Québec might want to see a particular schedule in America/Montreal zone while physically traveling in Tokyo Japan.
You can ask the user’s web browser or local JVM for its current default time zone. But ultimately, if critical, you must confirm the desired/expected time zone with the user.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
It's a common source of headache
In my experience, location by IP address is not always reliable, for example when people are using corporate VPNs.
You are correct, region-based time zones ("Europe/Paris", "CET") are preferable for properly handling DST.
I solved a similar problem with the following approach :
You associate a precise timezone to each user in your server-side database. When user fills a booking form you display a TZ selector, pre-filled with his default TZ. So he can double check it (IMHO much safer than guessing by IP) and on server side, Dates can be safely converted from local to server time and back.
Joda time might be able to solve your problem:
http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTimeZone.html

Categories

Resources