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.
Related
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…
I want to compare two dates.
If the current date time is greater or after the
specific date , then it will return 'True'.
So far I have tried this.
String deadline = "25/11/2017 11:00:00";
DateTime utc = new DateTime(DateTimeZone.UTC);
DateTimeZone timeZone = DateTimeZone.forID("Asia/Dhaka");
DateTime dhakaTime = utc.toDateTime(timeZone);
//Dead Line Time
DateTimeFormatter format = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime deadlineTime = format.parseDateTime(deadline.trim());
//Comapare
return deadlineTime.isAfter(dhakaTime.plusDays(2));
As today is 23 and dhakaTime.plusDays(2) will be 25 so it should return
"true".
But I am getting "false".
Output value :
dhakaTime.plusDays(2) = 2017-11-25T14:10:27.762+06:00
deadlineTime = 2017-11-25T11:00:00.000+06:00
Am i missing something or doing something wrong?
It gives false correctly.
You're comparing
deadLineTime = 2017-11-25T11:00:00.000+06:00 and
dhakaTime(+2) = 2017-11-25T14:10:27.762+06:00
They both are at same date, but with time, deadLineTime is at 11AM but dhakaTime(+2) is at 2PM. So,
(Nov 25, 2017 11AM)isAfter(Nov 25, 2017 2PM) is false.
EDIT: Testcases
As you mentioned you're testing, The following used different test cases for comparing deadLine with dhakaTime (+1, and +2 days). I hope this gives you an idea about how this works.
public static void main(String[] args) {
String deadline = "25/11/2017 11:00:00";
DateTime utc = new DateTime(DateTimeZone.UTC);
DateTimeZone timeZone = DateTimeZone.forID("Asia/Dhaka");
DateTime dhakaTime = utc.toDateTime(timeZone);
//Dead Line Time
DateTimeFormatter format = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime deadlineTime = format.parseDateTime(deadline.trim());
System.out.println("Deadline : " + deadline);
System.out.println("Current datetim : " + dhakaTime);
System.out.println("current datetime + 1 day : " + dhakaTime.plusDays(1));
System.out.println("current datetime + 2 day : " + dhakaTime.plusDays(2));
System.out.println("Is deadline after current datetime:" + deadlineTime.isAfter(dhakaTime));
System.out.println("Is deadline after current datetime + 1 day:" + deadlineTime.isAfter(dhakaTime.plusDays(1)));
System.out.println("Is deadline after current datetime + 2 day:" + deadlineTime.isAfter(dhakaTime.plusDays(2)));
}
Try using the method DateTimeFormatter withZone(DateTimeZone zone) and use that to create the DateTime
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.
I have a problem where i'm trying to find the date and time for a specific long value from the "new beginning of the universe", aka jan 1 1970.
I get a "cannot be dereferenced" error when i try to pass my new value to the toString thing.
What i don't get, is that this works for getting a time in millis and displaying it a more readable date/time format, so why not after i do a bunch of math with it?
import java.util.*;
public class Date {
public static void main(String[] args) {
Date mydate1 = new Date(10000);
System.out.println("The date and time of " +
mydate1.elapse + " from the Unix epoch is " + mydate1.getMyTime());
Date mydate2 = new Date(100000);
System.out.println("The date and time of " +
mydate2.elapse + " from the Unix epoch is " + mydate2.getMyTime());
Date mydate3 = new Date(1000000);
System.out.println("The date and time of " +
mydate3.elapse + " from the Unix epoch is " + mydate3.getMyTime());
Date mydate4 = new Date(10000000);
System.out.println("The date and time of " +
mydate4.elapse + " from the Unix epoch is " + mydate4.getMyTime());
Date mydate5 = new Date(100000000);
System.out.println("The date and time of " +
mydate5.elapse + " from the Unix epoch is " + mydate5.getMyTime());
Date mydate6 = new Date(1000000000);
System.out.println("The date and time of " +
mydate6.elapse + " from the Unix epoch is " + mydate6.getMyTime());
/*Date date7 = new Date(10000000000);
System.out.println("The date and time of " +
date7.elapse + " from the Unix epoch is " + date7.getTime());
Date date8 = new Date(100000000000);
System.out.println("The date and time of " +
date8.elapse + " from the Unix epoch is " + date8.getTime());*/
}
long elapse;
Date() {
elapse = 1;
}
Date(long elapseTime) {
elapse = elapseTime;
}
long getMyTime() {
//java.util.Date date = new.java.util.Date();
long currentMillis = System.currentTimeMillis();
long date = currentMillis + elapse - currentMillis;
System.out.println(date.toString());
You can't call toString() on a long (primitive type) -
// System.out.println(date.toString());
System.out.println(date); // <-- this would work.
System.out.println(String.valueOf(date)); // <-- this would be assignable to a
// String, but it prints the
// same value as the first example.
In
long date = currentMillis + elapse - currentMillis;
The variable date is a primitive (long) and not a object. toString is a method all java classes inherit from java.lang.Object and so will be available in all objects (that are instance of classes). long is just a primitive, primitives do not have methods, they do not inherit from Object either.
So all you need is
System.out.println(date);
The issue is in : System.out.println(date.toString())
date is of primitive type long (its not an object of wrapper class Long). Hence the method toString() is not available for 'date'. rather you can simple use :
System.out.println(date);
If you want to print the formatted Date use the following :
Dste d = new Date(date);
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
System.out.println(sdf.format(d));
Below is my code which checks the date which is stored in database with the current system date and calculates the days and if that days is lesser than the 180 days it will print something else print nothing,this code works great in an normal java program(with out using swings concept) if it is used with the swing program i changed the sql query to check get the date from the database based on the department and staff names which is entered in the text fields,i coded this code inside an jbutton,in the output it just prints the current system date but not calculates the days between the selected date and the current system dates,friends this is the problem am facing kindly need your help friends....thanks in advance..
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/leave", "root", "");
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery("select * from staff where depmt='" + txt1 + "' AND staffs='" + txt2 + "'");
Calendar javaCalendar = null;
String currentDate = "";
javaCalendar = Calendar.getInstance();
currentDate = javaCalendar.get(Calendar.DATE) + "/" + (javaCalendar.get(Calendar.MONTH) + 1) + "/" + javaCalendar.get(Calendar.YEAR);
int cdate = javaCalendar.get(Calendar.DATE);
int cmonth = (javaCalendar.get(Calendar.MONTH) + 1);
int cyear = javaCalendar.get(Calendar.YEAR);
int z = 0;
int date = 0, month = 0, year = 0;
System.out.println("Current Date\t" + currentDate);
System.out.println("\n");
while (rs.next()) {
date = rs.getInt(3);
month = rs.getInt(4);
year = rs.getInt(5);
System.out.println("Random Date\t" + date + "/" + month + "/" + year + "\n");
int d = (date - cdate);
int m = month - cmonth;
int y = year - cyear;
int d1 = java.lang.Math.abs(d);
int d2 = java.lang.Math.abs(m);
int d3 = java.lang.Math.abs(y);
z = d1 + (d2 * 30) + (d3 * 365);
if (z >= 180) {
System.out.println("something");
0
} else {
System.out.println("nothing");
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
//e.printStackTrace();
}
// TODO add your handling code here:
}
You should really use prepared statements cause this way your query is prone to sql injections.
Date formatter insted of concating string for currentdate
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(todaysDate);
Also it seems like your not closeing the connection that may be another issue.
Is there any reason for storeing the date in 3 separate columns?
Your algorithm to calculate the day difference between two dates is broken. It does not take in account different month lengths or leap years.
Unfortunately Java Calendar does not offer this feature at all. So either you apply your own homegrown algorithm (not easy, but in web there are some sources how to map a gregorian date to epoch days) or you use JodaTime like this way:
LocalDate db = new LocalDate(year, month, date);
int days = Days.daysBetween(db, LocalDate.now()).getDays();
Note that the result will be negative if db date is in the future. After all you can greatly shorten your code and abandon all Calendar stuff which is very bad for calculations of durations.
try this:
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
Date date1 = df.parse("14/02/2014");
Date date2 = df.parse("08/03/2014");
int days = Days.daysBetween(date1, date2).getDays();
Try this, by changing return value from millisecond to day.
public static int daysBetween(Date dateFrom, Date dateTo){
return (int)( (dateTo.getTime() - dateFrom.getTime()) / (1000 * 60 * 60 * 24));
}
Start Of Day
If you start with a mid-afternoon date-time object, go back 180 days by calculating seconds * minutes * hours * 180, you'll end up excluding the date-times earlier in that day 180 ago whereas I suppose you would want to include them. You should pay attention to when the day begins.
Time Zone
Both the question and other answers ignore the issue of time zone. Time zone defines the beginning of a day. Given the point about start of day (above), time zone is a related component.
Avoid java.util.Date & .Calendar
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them. Instead use either Joda-Time or the new java.time package in Java 8.
Joda-Time
Here is some example code using Joda-Time 2.3.
Note that while a Joda-Time DateTime object is similar to a java.util.Date, a DateTime does truly know its own assigned time zone.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeInQuestion = new DateTime( 2013, 6, 5, 4, 3, 2, timeZone );
DateTime now = new DateTime( timeZone );
DateTime hundredEightyDaysAgo = now.minusDays( 180 ).withTimeAtStartOfDay();
boolean isExpired = dateTimeInQuestion.isBefore( hundredEightyDaysAgo );
Dump to console…
System.out.println( "dateTimeInQuestion: " + dateTimeInQuestion );
System.out.println( "now: " + now );
System.out.println( "hundredEightyDaysAgo: " + hundredEightyDaysAgo );
System.out.println( "isExpired: " + isExpired );
When run…
dateTimeInQuestion: 2013-06-05T04:03:02.000+02:00
now: 2014-03-10T07:34:26.937+01:00
hundredEightyDaysAgo: 2013-09-11T00:00:00.000+02:00
isExpired: true