Android Time UTC - java

I am working on an Android app that frequently travels from Time Zone to TZ. I am getting various errors with times and TZs. The latest error is, when I load the flat file with times (see below), everything looks good. When I save the app environment (aka all variables/objects to sharedprefs), stop and then restart the app the time displayed is no longer local but UTC.
I began developing the app just using the default/local TZ. However, this became very complicated with DST and various TZs. Therefore my current approach is to store time in the app in UTC, and calculate differences between UTC times as needed. Then convert the UTC-stored time to the local TZ on-demand for user interaction.
I recognize there are many posts related to android time. I think I have read most if not all on java.util.date and Joda. However, I am still stuck. So, here goes...
I have 3 sources of time for the app. 1) I read in UTC Strings from a flat file 2) I get milliseconds since the Epoch for system time stamp (in UTC). 3) I get UTC in a string via a rest API. The app does numerous calculations between the 3 categories such as time difference, add time, etc. Below I will post my code for each of these
1 - Convert string UTCs that come from a file
public static Date string2date(String strformat, String strdate){
Date tdate = timestamp();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SimpleDateFormat formatter = new SimpleDateFormat(strformat);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateInString = strdate;
try {
tdate = formatter.parse(dateInString);
} catch (ParseException e) {
e.printStackTrace();
}
return tdate;
}
2 - Get milliseconds since Epoch
public static Date timestamp() {
Calendar localCalendar = Calendar.getInstance(TimeZone.getDefault());
//Date currentTime = localCalendar.getTime();
Date currentTime = GetUTCdatetimeAsDate();
return currentTime;
public static Date GetUTCdatetimeAsDate()
{
//note: doesn't check for null
return StringDateToDate(GetUTCdatetimeAsString());
}
public static String GetUTCdatetimeAsString()
{
final SimpleDateFormat sdf = new SimpleDateFormat(longdt);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date StringDateToDate(String StrDate)
{
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(longdt);
try
{
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
return dateToReturn;
}
3 - Get UTC in a string via a rest API (Format is "2017-02-10T01:09:00Z")
try {
Calendar tempCal = ISO8601.toCalendar(dateLocal);
Log.e (" fbu "," fsutc " + tempCal.getTime() );
ISODepDate = tempCal.getTime();
tempCal = ISO8601.toCalendar(dateLocal2);
ISOArrDate = tempCal.getTime();
//ab.setTimeZone(PST);
Log.e (" fbu "," fsutc " + dateLocal + " / " + dateLocal2);
Log.e (" fbu "," fsutc " + ISODepDate + " / " + ISOArrDate);
}
catch (Exception a){
int aa = 1;
Log.e (" exception "," a " + a);
}
public static Calendar toCalendar(final String iso8601string)
throws ParseException {
Calendar calendar = GregorianCalendar.getInstance();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
String s = iso8601string.replace(".000Z", "+00:00");
try {
s = s.substring(0, 22) + s.substring(23); // to get rid of the ":"
} catch (IndexOutOfBoundsException e) {
throw new ParseException("Invalid length", 0);
}
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
calendar.setTime(date);
return calendar;
}
4 - Finally, here is what I am using to "Display" the above 3 time categories in local time.
public String UTCtoLocal(Date indate, Boolean formatLong) {
Date utcDate = indate;
String result;
//Log.e( " utc "," indate " + indate);
/*utcDate = your own initialization here;*/
Date localDate = new Date(utcDate.getTime() + TimeZone.getDefault().getRawOffset());
//Log.e( " utc "," localdate " + localDate);
if (formatLong){
result = longd.format(localDate);
} else {
result = shortt.format(localDate);
}
return result;
The questions are, given the expectation that I store in UTC and display in Local, a) Have I implemented items 1-4 correctly? b) Will the above code actually store the times in UTC and display in local?
After flat file load everything looks good. After restart the times are displayed in UTC vs Local.

Related

Adjusting time correctly using DateTimeFormatter

I am creating an appointment app that has the capability to view monthly/weekly. The standard view, is able to show correct times in HH:mm, only between 9:00 - 17:00 . However, the monthly/weekly I can't convert and shows in full 24 hour time.
For the monthly I have:
public LocalTime getTime() {
return time;
}
#FXML
private void viewByMonthHandler(ActionEvent event) {
DataProvider.getAppointmentsByMonth().clear();
DataProvider.getAppointmentsByWeek().clear();
if(viewByMonthRadioButton.isSelected()) {
// I was using these two to try and convert
//DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
//DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("MMMM HH:mm");
Calendar cal = Calendar.getInstance();
String month = new SimpleDateFormat("MMMM").format(cal.getTime());
DataProvider.setMonthlyView(month);
}
sortAppointment();
viewByComboBox.setItems(viewByMonth);
}
I have tried :
String month = new DateTimeFormatter.ofPattern("MMMM HH:mm").format(cal.getTime());
and:
String month = new SimpleDateFormat("MMMM").format(timeFormat);
error:
Caused by: java.lang.IllegalArgumentException: Cannot format given Object as a Date
for the weekly I have:
#FXML
private void viewByWeekHandler(ActionEvent event) {
DataProvider.getAppointmentsByMonth().clear();
DataProvider.getAppointmentsByWeek().clear();
if(viewByWeekRadioButton.isSelected()) {
DataProvider.setWeeklyView(0);
}
sortAppointment();
viewByComboBox.setItems(viewByWeek);
}
setWeeklyView:
public static void setWeeklyView (int weekForReference) {
try {
ArrayList<Integer> selectedAppointmentsByWeek = new ArrayList<>();
Statement statement = DBConnection.getConnection().createStatement();
ResultSet weeklyAppointments = statement.executeQuery("SELECT appointmentId from appointment where year(start) = YEAR(date_add(curdate(), interval " + weekForReference + " WEEK)) and weekofyear(start) = weekofyear(date_add(curdate(),interval " + weekForReference + " WEEK));");
while(weeklyAppointments.next()) {
selectedAppointmentsByWeek.add(weeklyAppointments.getInt(1));
}
for(int appointmentId : selectedAppointmentsByWeek) {
ResultSet selectAppointment = statement.executeQuery("SELECT customer.customerName, customer.customerId, contact, title, type, location, description, start, end FROM appointment JOIN customer ON customer.customerId = appointment.customerId WHERE appointmentId =" + appointmentId);
selectAppointment.next();
Appointment appointment = new Appointment();
String customerName = selectAppointment.getString(1);
int customerId = selectAppointment.getInt(2);
String contact = selectAppointment.getString(3);
String title = selectAppointment.getString(4);
String type = selectAppointment.getString(5);
String location = selectAppointment.getString(6);
String description = selectAppointment.getString(7);
String start = selectAppointment.getString(8);
String end = selectAppointment.getString(9);
appointment.setCustomerName(customerName);
appointment.setContact(contact);
appointment.setTitle(title);
appointment.setType(type);
appointment.setLocation(location);
appointment.setDescription(description);
appointment.setStart(start);
appointment.setEnd(end);
appointmentsByWeek.add(appointment);
}
}
catch(SQLException ex) {
System.out.println("Error " + ex.getMessage());
}
}
The setMonthlyView is almost identical, just replacing weekly with monthly. How could I go about formatting these so they are no longer HH:mm:ss.S and in between 9:00-17:00? I have taken the advice previously given to me for the little parts, and still can't figure it out. Thank you so much for taking the time to read and help.
Do one of these do what you want.
12 hour
String localDateTime12Hour =
LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMMM hh:mm a"));
System.out.println(localDateTime12Hour);
24 hour
String localDateTime24Hour =
LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMMM HH:mm"));
System.out.println(localDateTime24Hour);
Prints
July 06:11 PM
July 18:11
Use HH for 24 hour
Use hh for 12 hour (the a provides AM or PM)
Remember to use LocalDateTime and not LocalTime when specifying formatter attributes like MMMM. You are returning a LocalTime object in your getTime() method. And I would avoid using Calendar and Date as they are outmoded. Use classes from the java.time package.

The method getTime() is undefined for the type Object — what’s wrong?

I have created an application that generates a difference between two dates when u click on a button named "calculate difference", but I don't know whats wrong with this code. I tried different methods and without any result. If you can help me I will be grateful guys.
public class DateForm extends javax.swing.JPanel {
String date1 = "26/02/2011";
String time1 = "11:00 AM";
String date2 = "27/02/2011";
String time2 = "12:15 AM";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
private Object dateObj1;
private Object dateObj2;
public DateForm() {
initComponents();
}
private void btnActionPerformed(java.awt.event.ActionEvent evt) {
try {
Date dateObj1 = sdf.parse(date1 + " " + time1);
} catch (ParseException ex) {
Logger.getLogger(DateForm.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Date dateObj2 = sdf.parse(date2 + " " + time2); // TODO add your handling code here:
} catch (ParseException ex) {
Logger.getLogger(DateForm.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(dateObj1);
System.out.println(dateObj2);
long diff = dateObj2.getTime() - dateObj1.getTime();
double diffInHours = diff / ((double) 1000 * 60 * 60);
System.out.println(diffInHours);
System.out.println("Hours " + (int)diffInHours);
System.out.println("Minutes " + (diffInHours - (int)diffInHours)*60 );
}
}
Since it's 2018, you really should be making use of the date/time APIs introduced in Java 8 (or the ThreeTen Backport if you're Java 7 or below)
String date1 = "26/02/2011";
String time1 = "11:00 AM";
String date2 = "27/02/2011";
String time2 = "12:15 AM";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm a");
LocalDateTime start = LocalDateTime.parse(date1 + " " + time1, formatter);
LocalDateTime end = LocalDateTime.parse(date2 + " " + time2, formatter);
Duration duration = Duration.between(start, end);
long hours = duration.toHours();
long mins = duration.minusHours(hours).toMinutes();
// Or if you're using Java 9+
//long mins = duration.toMinutesPart();
System.out.println("Hours = " + hours);
System.out.println("Mins = " + mins);
which ouputs
Hours = 13
Mins = 15
I would recommend having a read of Date and Time Classes
"whats wrong with this code please?"
The following...
try {
Date dateObj1 = sdf.parse(date1 + " " + time1);
} catch (ParseException ex) {
Logger.getLogger(DateForm.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Date dateObj2 = sdf.parse(date2 + " " + time2); // TODO add your handling code here:
} catch (ParseException ex) {
Logger.getLogger(DateForm.class.getName()).log(Level.SEVERE, null, ex);
}
Is simply creating two objects whose scope is only relevant to the try-catch blocks they are defined in, dateObj1 and dateObj2 can't be accessed outside of those blocks ... but ...
You define...
private Object dateObj1;
private Object dateObj2;
as instance fields, which means...
System.out.println(dateObj1);
System.out.println(dateObj2);
will most likely print null and...
long diff = dateObj2.getTime() - dateObj1.getTime();
won't compile, because dateObj1 and dateObj2 are just defined as Object and Object doesn't have a getTime method
Date/time calculations are complex and governed by many different rules (further complicated by the type of calendar you are using)
Simply doing...
double diffInHours = diff / ((double) 1000 * 60 * 60);
is naive at best, broken at worst
And...
System.out.println("Minutes " + (diffInHours - (int)diffInHours)*60 );
is well, pointless, what's (something - something) * 60?
MadProgrammer’s answer is a very good one. I’d just like to supply a detail: Depending on taste you may parse the date and time strings separately and combine them after parsing:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
DateTimeFormatter timeFormatter
= DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
String date1 = "26/02/2011";
String time1 = "11:00 AM";
LocalDateTime start = LocalDate.parse(date1, dateFormatter)
.atTime(LocalTime.parse(time1, timeFormatter));
System.out.println(start);
Output is:
2011-02-26T11:00
One potential advantage is in case of a bug in one of the parsed string you will get a preciser error message.
And one more detail now I’m at it: specify locale. AM and PM are called other things in other languages, so to make sure that your code works on other computers and also on the day when you play with your regional settings…

Java SimpleDateFormat not accepting ##/##

Below, I've got the code I'm trying to use. It always hits the catch, returning a null. Both month and day are integers, and they've already been checked to ensure they fall within existing dates on existing days. Regardless, I'm testing with "05" for the month and "02" for the day. Does an input of ##/## not work, for some reason?
public static Date getAlphabetDate()
{
try
{
String tempDate = month + "/" + day;
Date alphabetDate = new SimpleDateFormat("MMMM d").parse(tempDate);
return alphabetDate;
}
catch(Exception e)
{
return null;
}
}
EDIT: I'm trying to format this output so it looks like "May 02". When I look at the documentation, I see a huge section of the page is dedicated to formatting output. Why isn't mine formatting like that?
If your input is 02/05, you should use the corresponding date format:
public static Date getAlphabetDate()
{
try
{
String tempDate = month + "/" + day;
Date alphabetDate = new SimpleDateFormat("MM/dd").parse(tempDate);
return alphabetDate;
}
catch(Exception e)
{
return null;
}
}
you are parsing the string in the simpledataformat the wrongway..
try this:
String tempDate = month + "/" + day;
Date alphabetDate = new SimpleDateFormat("MM/d").parse(tempDate);
Your input doesn't match your format pattern...
Your input is in the form of MM/dd but you pattern is in the format of MMMM d, you will need to make one of these match
Try using
String tempDate = month + " " + day;
Date alphabetDate = new SimpleDateFormat("MM d").parse(tempDate);
Instead, for example...

Joda DateTime to Timestamp conversion

I am trying to change the value of Timestamp by DateTimeZone in Joda :
DateTime dt = new DateTime(rs.getTimestamp("anytimestampcolumn"),
DateTimeZone.forID("anytimezone"));
Timestamp ts = new Timestamp(dt.getMillis());
For DateTime, value is : 2013-04-13T22:56:27.000+03:00
For TimeStamp, value is : 2013-04-13 22:56:27.0
Timestamp is coming without timezone difference.
How can I get the correct Timestamp with TimeZone ?
For example I want to get "2013-05-13 01:56:27.0".
Edit : using MySQL, column type is TIMESTAMP of course, rs is ResultSet.
It is a common misconception that time (a measurable 4th dimension) is different over the world. Timestamp as a moment in time is unique. Date however is influenced how we "see" time but actually it is "time of day".
An example: two people look at the clock at the same moment. The timestamp is the same, right?
But one of them is in London and sees 12:00 noon (GMT, timezone offset is 0), and the other is in Belgrade and sees 14:00 (CET, Central Europe, daylight saving now, offset is +2).
Their perception is different but the moment is the same.
You can find more details in this answer.
UPDATE
OK, it's not a duplicate of this question but it is pointless since you are confusing the terms "Timestamp = moment in time (objective)" and "Date[Time] = time of day (subjective)".
Let's look at your original question code broken down like this:
// Get the "original" value from database.
Timestamp momentFromDB = rs.getTimestamp("anytimestampcolumn");
// Turn it into a Joda DateTime with time zone.
DateTime dt = new DateTime(momentFromDB, DateTimeZone.forID("anytimezone"));
// And then turn it back into a timestamp but "with time zone".
Timestamp ts = new Timestamp(dt.getMillis());
I haven't run this code but I am certain it will print true and the same number of milliseconds each time:
System.out.println("momentFromDB == dt : " + (momentFromDB.getTime() == dt.getTimeInMillis());
System.out.println("momentFromDB == ts : " + (momentFromDB.getTime() == ts.getTime()));
System.out.println("dt == ts : " + (dt.getTimeInMillis() == ts.getTime()));
System.out.println("momentFromDB [ms] : " + momentFromDB.getTime());
System.out.println("ts [ms] : " + ts.getTime());
System.out.println("dt [ms] : " + dt.getTimeInMillis());
But as you said yourself printing them out as strings will result in "different" time because DateTime applies the time zone. That's why "time" is stored and transferred as Timestamp objects (which basically wraps a long) and displayed or entered as Date[Time].
In your own answer you are artificially adding an offset and creating a "wrong" time.
If you use that timestamp to create another DateTime and print it out it will be offset twice.
// Turn it back into a Joda DateTime with time zone.
DateTime dt = new DateTime(ts, DateTimeZone.forID("anytimezone"));
P.S. If you have the time go through the very complex Joda Time source code to see how it holds the time (millis) and how it prints it.
JUnit Test as proof
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.Before;
import org.junit.Test;
public class WorldTimeTest {
private static final int MILLIS_IN_HOUR = 1000 * 60 * 60;
private static final String ISO_FORMAT_NO_TZ = "yyyy-MM-dd'T'HH:mm:ss.SSS";
private static final String ISO_FORMAT_WITH_TZ = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
private TimeZone londonTimeZone;
private TimeZone newYorkTimeZone;
private TimeZone sydneyTimeZone;
private long nowInMillis;
private Date now;
public static SimpleDateFormat createDateFormat(String pattern, TimeZone timeZone) throws Exception {
SimpleDateFormat result = new SimpleDateFormat(pattern);
// Must explicitly set the time zone with "setCalendar()".
result.setCalendar(Calendar.getInstance(timeZone));
return result;
}
public static SimpleDateFormat createDateFormat(String pattern) throws Exception {
return createDateFormat(pattern, TimeZone.getDefault());
}
public static SimpleDateFormat createDateFormat() throws Exception {
return createDateFormat(ISO_FORMAT_WITH_TZ, TimeZone.getDefault());
}
public void printSystemInfo() throws Exception {
final String[] propertyNames = {
"java.runtime.name", "java.runtime.version", "java.vm.name", "java.vm.version",
"os.name", "os.version", "os.arch",
"user.language", "user.country", "user.script", "user.variant",
"user.language.format", "user.country.format", "user.script.format",
"user.timezone" };
System.out.println();
System.out.println("System Information:");
for (String name : propertyNames) {
if (name == null || name.length() == 0) {
continue;
}
String value = System.getProperty(name);
if (value != null && value.length() > 0) {
System.out.println(" " + name + " = " + value);
}
}
final TimeZone defaultTZ = TimeZone.getDefault();
final int defaultOffset = defaultTZ.getOffset(nowInMillis) / MILLIS_IN_HOUR;
final int userOffset = TimeZone.getTimeZone(System
.getProperty("user.timezone")).getOffset(nowInMillis) / MILLIS_IN_HOUR;
final Locale defaultLocale = Locale.getDefault();
System.out.println(" default.timezone-offset (hours) = " + userOffset);
System.out.println(" default.timezone = " + defaultTZ.getDisplayName());
System.out.println(" default.timezone.id = " + defaultTZ.getID());
System.out.println(" default.timezone-offset (hours) = " + defaultOffset);
System.out.println(" default.locale = "
+ defaultLocale.getLanguage() + "_" + defaultLocale.getCountry()
+ " (" + defaultLocale.getDisplayLanguage()
+ "," + defaultLocale.getDisplayCountry() + ")");
System.out.println(" now = " + nowInMillis + " [ms] or "
+ createDateFormat().format(now));
System.out.println();
}
#Before
public void setUp() throws Exception {
// Remember this moment.
now = new Date();
nowInMillis = now.getTime(); // == System.currentTimeMillis();
// Print out some system information.
printSystemInfo();
// "Europe/London" time zone is DST aware, we'll use fixed offset.
londonTimeZone = TimeZone.getTimeZone("GMT");
// The same applies to "America/New York" time zone ...
newYorkTimeZone = TimeZone.getTimeZone("GMT-5");
// ... and for the "Australia/Sydney" time zone.
sydneyTimeZone = TimeZone.getTimeZone("GMT+10");
}
#Test
public void testDateFormatting() throws Exception {
int londonOffset = londonTimeZone.getOffset(nowInMillis) / MILLIS_IN_HOUR; // in hours
Calendar londonCalendar = Calendar.getInstance(londonTimeZone);
londonCalendar.setTime(now);
int newYorkOffset = newYorkTimeZone.getOffset(nowInMillis) / MILLIS_IN_HOUR;
Calendar newYorkCalendar = Calendar.getInstance(newYorkTimeZone);
newYorkCalendar.setTime(now);
int sydneyOffset = sydneyTimeZone.getOffset(nowInMillis) / MILLIS_IN_HOUR;
Calendar sydneyCalendar = Calendar.getInstance(sydneyTimeZone);
sydneyCalendar.setTime(now);
// Check each time zone offset.
assertThat(londonOffset, equalTo(0));
assertThat(newYorkOffset, equalTo(-5));
assertThat(sydneyOffset, equalTo(10));
// Check that calendars are not equals (due to time zone difference).
assertThat(londonCalendar, not(equalTo(newYorkCalendar)));
assertThat(londonCalendar, not(equalTo(sydneyCalendar)));
// Check if they all point to the same moment in time, in milliseconds.
assertThat(londonCalendar.getTimeInMillis(), equalTo(nowInMillis));
assertThat(newYorkCalendar.getTimeInMillis(), equalTo(nowInMillis));
assertThat(sydneyCalendar.getTimeInMillis(), equalTo(nowInMillis));
// Check if they all point to the same moment in time, as Date.
assertThat(londonCalendar.getTime(), equalTo(now));
assertThat(newYorkCalendar.getTime(), equalTo(now));
assertThat(sydneyCalendar.getTime(), equalTo(now));
// Check if hours are all different (skip local time because
// this test could be executed in those exact time zones).
assertThat(newYorkCalendar.get(Calendar.HOUR_OF_DAY),
not(equalTo(londonCalendar.get(Calendar.HOUR_OF_DAY))));
assertThat(sydneyCalendar.get(Calendar.HOUR_OF_DAY),
not(equalTo(londonCalendar.get(Calendar.HOUR_OF_DAY))));
// Display London time in multiple forms.
SimpleDateFormat dfLondonNoTZ = createDateFormat(ISO_FORMAT_NO_TZ, londonTimeZone);
SimpleDateFormat dfLondonWithTZ = createDateFormat(ISO_FORMAT_WITH_TZ, londonTimeZone);
System.out.println("London (" + londonTimeZone.getDisplayName(false, TimeZone.SHORT)
+ ", " + londonOffset + "):");
System.out.println(" time (ISO format w/o TZ) = "
+ dfLondonNoTZ.format(londonCalendar.getTime()));
System.out.println(" time (ISO format w/ TZ) = "
+ dfLondonWithTZ.format(londonCalendar.getTime()));
System.out.println(" time (default format) = "
+ londonCalendar.getTime() + " / " + londonCalendar.toString());
// Using system default time zone.
System.out.println(" time (default TZ) = "
+ createDateFormat(ISO_FORMAT_NO_TZ).format(londonCalendar.getTime())
+ " / " + createDateFormat().format(londonCalendar.getTime()));
// Display New York time in multiple forms.
SimpleDateFormat dfNewYorkNoTZ = createDateFormat(ISO_FORMAT_NO_TZ, newYorkTimeZone);
SimpleDateFormat dfNewYorkWithTZ = createDateFormat(ISO_FORMAT_WITH_TZ, newYorkTimeZone);
System.out.println("New York (" + newYorkTimeZone.getDisplayName(false, TimeZone.SHORT)
+ ", " + newYorkOffset + "):");
System.out.println(" time (ISO format w/o TZ) = "
+ dfNewYorkNoTZ.format(newYorkCalendar.getTime()));
System.out.println(" time (ISO format w/ TZ) = "
+ dfNewYorkWithTZ.format(newYorkCalendar.getTime()));
System.out.println(" time (default format) = "
+ newYorkCalendar.getTime() + " / " + newYorkCalendar.toString());
// Using system default time zone.
System.out.println(" time (default TZ) = "
+ createDateFormat(ISO_FORMAT_NO_TZ).format(newYorkCalendar.getTime())
+ " / " + createDateFormat().format(newYorkCalendar.getTime()));
// Display Sydney time in multiple forms.
SimpleDateFormat dfSydneyNoTZ = createDateFormat(ISO_FORMAT_NO_TZ, sydneyTimeZone);
SimpleDateFormat dfSydneyWithTZ = createDateFormat(ISO_FORMAT_WITH_TZ, sydneyTimeZone);
System.out.println("Sydney (" + sydneyTimeZone.getDisplayName(false, TimeZone.SHORT)
+ ", " + sydneyOffset + "):");
System.out.println(" time (ISO format w/o TZ) = "
+ dfSydneyNoTZ.format(sydneyCalendar.getTime()));
System.out.println(" time (ISO format w/ TZ) = "
+ dfSydneyWithTZ.format(sydneyCalendar.getTime()));
System.out.println(" time (default format) = "
+ sydneyCalendar.getTime() + " / " + sydneyCalendar.toString());
// Using system default time zone.
System.out.println(" time (default TZ) = "
+ createDateFormat(ISO_FORMAT_NO_TZ).format(sydneyCalendar.getTime())
+ " / " + createDateFormat().format(sydneyCalendar.getTime()));
}
#Test
public void testDateParsing() throws Exception {
// Create date parsers that look for time zone information in a date-time string.
final SimpleDateFormat londonFormatTZ = createDateFormat(ISO_FORMAT_WITH_TZ, londonTimeZone);
final SimpleDateFormat newYorkFormatTZ = createDateFormat(ISO_FORMAT_WITH_TZ, newYorkTimeZone);
final SimpleDateFormat sydneyFormatTZ = createDateFormat(ISO_FORMAT_WITH_TZ, sydneyTimeZone);
// Create date parsers that ignore time zone information in a date-time string.
final SimpleDateFormat londonFormatLocal = createDateFormat(ISO_FORMAT_NO_TZ, londonTimeZone);
final SimpleDateFormat newYorkFormatLocal = createDateFormat(ISO_FORMAT_NO_TZ, newYorkTimeZone);
final SimpleDateFormat sydneyFormatLocal = createDateFormat(ISO_FORMAT_NO_TZ, sydneyTimeZone);
// We are looking for the moment this millenium started, the famous Y2K,
// when at midnight everyone welcomed the New Year 2000, i.e. 2000-01-01 00:00:00.
// Which of these is the right one?
// a) "2000-01-01T00:00:00.000-00:00"
// b) "2000-01-01T00:00:00.000-05:00"
// c) "2000-01-01T00:00:00.000+10:00"
// None of them? All of them?
// For those who guessed it - yes, it is a trick question because we didn't specify
// the "where" part, or what kind of time (local/global) we are looking for.
// The first (a) is the local Y2K moment in London, which is at the same time global.
// The second (b) is the local Y2K moment in New York, but London is already celebrating for 5 hours.
// The third (c) is the local Y2K moment in Sydney, and they started celebrating 15 hours before New York did.
// The point here is that each answer is correct because everyone thinks of that moment in terms of "celebration at midnight".
// The key word here is "midnight"! That moment is actually a "time of day" moment illustrating our perception of time based on the movement of our Sun.
// These are global Y2K moments, i.e. the same moment all over the world, UTC/GMT midnight.
final String MIDNIGHT_GLOBAL = "2000-01-01T00:00:00.000-00:00";
final Date milleniumInLondon = londonFormatTZ.parse(MIDNIGHT_GLOBAL);
final Date milleniumInNewYork = newYorkFormatTZ.parse(MIDNIGHT_GLOBAL);
final Date milleniumInSydney = sydneyFormatTZ.parse(MIDNIGHT_GLOBAL);
// Check if they all point to the same moment in time.
// And that parser ignores its own configured time zone and uses the information from the date-time string.
assertThat(milleniumInNewYork, equalTo(milleniumInLondon));
assertThat(milleniumInSydney, equalTo(milleniumInLondon));
// These are all local Y2K moments, a.k.a. midnight at each location on Earth, with time zone information.
final String MIDNIGHT_LONDON = "2000-01-01T00:00:00.000-00:00";
final String MIDNIGHT_NEW_YORK = "2000-01-01T00:00:00.000-05:00";
final String MIDNIGHT_SYDNEY = "2000-01-01T00:00:00.000+10:00";
final Date midnightInLondonTZ = londonFormatLocal.parse(MIDNIGHT_LONDON);
final Date midnightInNewYorkTZ = newYorkFormatLocal.parse(MIDNIGHT_NEW_YORK);
final Date midnightInSydneyTZ = sydneyFormatLocal.parse(MIDNIGHT_SYDNEY);
// Check if they all point to the same moment in time.
assertThat(midnightInNewYorkTZ, not(equalTo(midnightInLondonTZ)));
assertThat(midnightInSydneyTZ, not(equalTo(midnightInLondonTZ)));
// Check if the time zone offset is correct.
assertThat(midnightInLondonTZ.getTime() - midnightInNewYorkTZ.getTime(),
equalTo((long) newYorkTimeZone.getOffset(milleniumInLondon.getTime())));
assertThat(midnightInLondonTZ.getTime() - midnightInSydneyTZ.getTime(),
equalTo((long) sydneyTimeZone.getOffset(milleniumInLondon.getTime())));
// These are also local Y2K moments, just withouth the time zone information.
final String MIDNIGHT_ANYWHERE = "2000-01-01T00:00:00.000";
final Date midnightInLondon = londonFormatLocal.parse(MIDNIGHT_ANYWHERE);
final Date midnightInNewYork = newYorkFormatLocal.parse(MIDNIGHT_ANYWHERE);
final Date midnightInSydney = sydneyFormatLocal.parse(MIDNIGHT_ANYWHERE);
// Check if these are the same as the local moments with time zone information.
assertThat(midnightInLondon, equalTo(midnightInLondonTZ));
assertThat(midnightInNewYork, equalTo(midnightInNewYorkTZ));
assertThat(midnightInSydney, equalTo(midnightInSydneyTZ));
// Check if they all point to the same moment in time.
assertThat(midnightInNewYork, not(equalTo(midnightInLondon)));
assertThat(midnightInSydney, not(equalTo(midnightInLondon)));
// Check if the time zone offset is correct.
assertThat(midnightInLondon.getTime() - midnightInNewYork.getTime(),
equalTo((long) newYorkTimeZone.getOffset(milleniumInLondon.getTime())));
assertThat(midnightInLondon.getTime() - midnightInSydney.getTime(),
equalTo((long) sydneyTimeZone.getOffset(milleniumInLondon.getTime())));
// Final check - if Y2K moment is in London ..
final String Y2K_LONDON = "2000-01-01T00:00:00.000Z";
// .. New York local time would be still 5 hours in 1999 ..
final String Y2K_NEW_YORK = "1999-12-31T19:00:00.000-05:00";
// .. and Sydney local time would be 10 hours in 2000.
final String Y2K_SYDNEY = "2000-01-01T10:00:00.000+10:00";
final String londonTime = londonFormatTZ.format(milleniumInLondon);
final String newYorkTime = newYorkFormatTZ.format(milleniumInLondon);
final String sydneyTime = sydneyFormatTZ.format(milleniumInLondon);
// WHat do you think, will the test pass?
assertThat(londonTime, equalTo(Y2K_LONDON));
assertThat(newYorkTime, equalTo(Y2K_NEW_YORK));
assertThat(sydneyTime, equalTo(Y2K_SYDNEY));
}
}
Actually this is not a duplicate question. And this how i solve my problem after several times :
int offset = DateTimeZone.forID("anytimezone").getOffset(new DateTime());
This is the way to get offset from desired timezone.
Let's return to our code, we were getting timestamp from a result set of query, and using it with timezone to create our datetime.
DateTime dt = new DateTime(rs.getTimestamp("anytimestampcolumn"),
DateTimeZone.forID("anytimezone"));
Now we will add our offset to the datetime, and get the timestamp from it.
dt = dt.plusMillis(offset);
Timestamp ts = new Timestamp(dt.getMillis());
May be this is not the actual way to get it, but it solves my case. I hope it helps anyone who is stuck here.
//This Works just fine
DateTime dt = new DateTime();
Log.d("ts",String.valueOf(dt.now()));
dt=dt.plusYears(3);
dt=dt.minusDays(7);
Log.d("JODA DateTime",String.valueOf(dt));
Timestamp ts= new Timestamp(dt.getMillis());
Log.d("Coverted to java.sql.Timestamp",String.valueOf(ts));
I've solved this problem in this way.
String dateUTC = rs.getString("date"); //UTC
DateTime date;
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZoneUTC();
date = dateTimeFormatter.parseDateTime(dateUTC);
In this way you ignore the server TimeZone forcing your chosen TimeZone.

Converting EDT time zone to GMT not working fine in java

I am using this code to parse this date. It must show new date as "2012-06-20 03:09:38" as EDT is -4GMT and my current location is GMT+5. But its not showing this it now showing as it is
private static void convertEDT_TO_GMT() {
try {
String s = "2012-06-20 18:09:38";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("EDT"));
Date timestamp = null;
timestamp = df.parse(s);
df.setTimeZone(TimeZone.getTimeZone("GMT+05:00"));
System.out.println("Old = " + s);
String parsed = df.format(timestamp);
System.out.println("New = " + parsed);
} catch (Exception e) {
e.printStackTrace();
}
}
It show
Old = 2012-06-20 18:09:38
New = 2012-06-20 23:09:38
The time zone 'EDT' does not exist. Doing a System.out.println() of `TimeZone.getTimeZone("EDT") shows that it is falling back to GMT because Java does not know 'EDT' as a time zone.
Changing from "EDT" to "GMT-04:00" gives the correct result:
try {
String s = "2012-06-20 18:09:38";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//df.setTimeZone(TimeZone.getTimeZone("EDT"));
df.setTimeZone(TimeZone.getTimeZone("GMT-04:00"));
Date timestamp = null;
timestamp = df.parse(s);
df.setTimeZone(TimeZone.getTimeZone("GMT+05:00"));
System.out.println("Old = " + s);
String parsed = df.format(timestamp);
System.out.println("New = " + parsed);
} catch (Exception e) {
e.printStackTrace();
}
Result:
Old = 2012-06-20 18:09:38
New = 2012-06-21 03:09:38
According to this post:
Eastern Daylight Time isn't the name of a "full" time zone - it's "half" a time zone, effectively, always 4 hours behind UTC.
So using "GMT-04:00" might be the right solution.
TimeZone.setDefault(TimeZone.getTimeZone("GMT-04:00"));
Date date = new Date();
System.out.println("Current EDT Time is : "+date);

Categories

Resources