I need to save a few dates in SharedPreferences in android and retrieve it. I am building reminder app using AlarmManager and I need to save list of future dates. It must be able to retrieve as milliseconds. First I thought to calculate time between today now time and future time and store in shared preference. But that method is not working since I need to use it for AlarmManager.
To save and load accurate date, you could use the long (number) representation of a Date object.
Example:
//getting the current time in milliseconds, and creating a Date object from it:
Date date = new Date(System.currentTimeMillis()); //or simply new Date();
//converting it back to a milliseconds representation:
long millis = date.getTime();
You can use this to save or retrieve Date/Time data from SharedPreferences like this
Save:
SharedPreferences prefs = ...;
prefs.edit().putLong("time", date.getTime()).apply();
Read it back:
Date myDate = new Date(prefs.getLong("time", 0));
Edit
If you want to store the TimeZone additionaly, you could write some helper method for that purpose, something like this (I have not tested them, feel free to correct it, if something is wrong):
public static Date getDate(final SharedPreferences prefs, final String key, final Date defValue) {
if (!prefs.contains(key + "_value") || !prefs.contains(key + "_zone")) {
return defValue;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(prefs.getLong(key + "_value", 0));
calendar.setTimeZone(TimeZone.getTimeZone(prefs.getString(key + "_zone", TimeZone.getDefault().getID())));
return calendar.getTime();
}
public static void putDate(final SharedPreferences prefs, final String key, final Date date, final TimeZone zone) {
prefs.edit().putLong(key + "_value", date.getTime()).apply();
prefs.edit().putString(key + "_zone", zone.getID()).apply();
}
You can do this:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.US);
To save a date:
preferences .edit().putString("mydate", sdf.format(date)).apply();
To retrieve:
try{
Date date = sdf.parse(preferences.getString("myDate", "defaultValue"));
} catch (ParseException e) {
e.printStackTrace();
}
Hope it help.
tl;dr
The modern approach uses java.time classes and ISO 8601 strings.
Reading.
Instant // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochMilli(
Long.getLong( incomingText )
) // Returns a `Instant` object.
.atZone( // Adjust from UTC to some time zone. Same moment, same point on the timeline, different wall-clock time.
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
Writing.
ZonedDateTime
.of(
LocalDate.of( 2018 , Month.JANUARY , 23 ) ,
LocalTime.of( 15 , 35 ) ,
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
.toInstant() // Returns an `Instant`. Adjust from a time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
.toEpochMilli() // Returns a `long` integer number primitive. Any microseconds or nanoseconds are ignored, of course.
If your alarm manager has not yet been modernized to handle java.time objects, convert between legacy & modern classes using new methods added to the old classes.
java.util.Date d = java.util.Date.from( instant ) ;
…and…
Instant instant = d.toInstant() ;
java.time
The troublesome old date-time classes were supplanted by the java.time classes.
For a moment in UTC, with a resolution of nanoseconds, use Instant.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
You want only milliseconds for your needs, so truncate any microseconds & nanoseconds.
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;
To determine a moment by date and time-of-day requires a time zone. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Combine with a time-of-day, a LocalTime.
LocalTime lt = LocalTime.of( 14 , 0 ) ;
Wrap it all together as a ZonedDateTime object.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Adjust to UTC by extracting a Instant.
Instant instant = zdt.toInstant() ;
Extract your desired count-of-milliseconds since the epoch reference of first moment of 1970 in UTC. Again, be aware that any micros/nanos in your Instant will be ignored when extracting milliseconds.
long milliseconds = instant.toEpochMilli() ; // Be aware of potential data loss, ignoring any microseconds or nanoseconds.
Read those milliseconds back from storage as text using the Long class.
long milliseconds = Long.getLong( incomingText ) ;
Instant instant = Instant.ofEpochMilli( milliseconds ) ;
To see that moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
To generate text representing that value, use DateTimeFormatter.ofLocalizedDateTime to automatically localize.
Tip: Consider writing your date-time values to storage in standard ISO 8601 format rather than as a count-of-milliseconds. The milliseconds cannot be read meaningfully by humans, making debugging & monitoring tricky.
String output = instant.toString() ;
2018-10-05T20:28:48.584Z
Instant instant = Instant.parse( 2018-10-05T20:28:48.584Z ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
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….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I'm writing automated bdds for a rest API. And the API returns a date. I want to get the difference between the returned date from the API and the current date today.
So for example, the API returns "March 13, 2018 12:00 pm"
And today's date is "March 11, 2018 12:00pm"
The times are always the same, it's only the days that change. And the API will also return a date that's in the future.
I have this piece of code:
Date currentDate = Date.from(Instant.now());
// endDate comes from the API
long diff = endDate.getTime() - currentDate.getTime();
long differenceInDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
This returns 1, but I want it to include the last day. I can just add +1 at the end of endDate.getTime() - currentDate.getTime(); but I'm not sure if that's the right approach.
I also read that this is not a good solution in general, because it doesn't account for daylight savings time. I'm not sure how or if it would affect my automated bdds when daylight savings comes. What's the best way to capture the difference in days?
Think of it as how many days do I have left until expiration
Your real problem is that your backend REST service is poorly designed.
ISO 8601
First of all, date-time values exchanged should be in standard ISO 8601 format, not some localized presentation string.
The standard formats are used by default in the java.time classes when parsing/generating text.
java.time
Never use the terrible Date class. That class, along with Calendar, SimpleDateFormat, and such, was supplanted years ago by the java.time classes defined in JSR 310.
Date.from(Instant.now())
Never mix the terrible legacy date-time classes (Date) with their replacements (Instant), the modern java.time classes. Mixing these is unnecessary and confusing.
The java.time classes entirely replace their predecessors.
The times are always the same, it's only the days that change. And the API will also return a date that's in the future.
If you only want to exchange date values, without a time-of-day and without a time zone or offset, use LocalDate class, and exchange the ISO 8601 format YYYY-MM-DD such as 2018-03-11. Call LocalDate.parse and LocalDate::toString.
long differenceInDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
Representing a count of days as a count of milliseconds without the context of a time zone or offset-from-UTC is reckless. Days are not always 24 hours long. They can be 23, 23.5, 25, or some other number of hours.
If you mean to use UTC so as to always have 24-hour days, say so. Represent your date-time with an indication of time zone or offset. For example, the standard format: 2018-03-11T00:00Z where the Z on the end means UTC and is pronounced “Zulu”.
So your entire problem could be reduced to this one-liner.
ChronoUnit.DAYS.between(
LocalDate.now( ZoneId.of( "America/Montreal" ) ) , // Get the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
LocalDate.parse( "2019-01-23" ) // Parse a string in standard ISO 8601 format for a date-only value.
) // Returns a `long` integer number of days elapsed.
Unzoned
If you are not in a position to clean up all those messy design problems, then let's forge ahead, trying to use this messy data.
First fix the am/pm which should be in uppercase.
String input = "March 13, 2018 12:00 pm".replace( " am" , " AM" ).replace( " pm" , " PM" );
Define a formatting pattern to match your input string.
Specify a Locale to determine the human language and cultural norms to use in translating the text.
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMMM d, uuuu HH:mm a" );
Parse as a LocalDateTime because your input lacks an indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString(): 2018-03-13T12:00
A LocalDateTime purposely has no concept of time zone or offset-from-UTC. So this class cannot represent a moment, is not a point on the timeline.
If you want generic 24-hour days without regard to the reality of anomalies in wall-clock time used by various people in various places, such as Daylight Saving Time (DST), we can continue to use this class.
Get the current date as seen in the wall-clock time used the people to whom your app is aimed (a time zone).
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Get noon on that date, in no particular time zone.
LocalDateTime ldtTodayNoon = LocalDateTime.of( today , LocalTime.NOON ) ;
Count days elapsed.
long daysElapsed =
ChronoUnit.DAYS.between(
ldtTodayNoon ,
ldt
)
;
Of course we could just as well have done this using only LocalDate rather than LocalDateTime, but I followed your problem statement as written.
Notice that in your given example, the string represents a date in the past. So our number of days will be negative.
Zoned
If you did want to account for anomalies seen on some dates in some zones, then you should have represented a moment properly, as discussed above, with an indicator of time zone or offset-from-UTC.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
ZonedDateTime zdtNow = ZonedDateTime.now( z ) ;
Or perhaps you want noon today in the desired time zone. If noon is not a valid time-of-day on this date in this zone, the ZonedDateTime class will adjust. Be sure to read the ZonedDateTime.of JavaDoc to understand the algorithm of that adjustment.
LocalDate today = LocalDate.now( z ) ;
ZonedDateTime zdtTodayNoon = ZonedDateTime.of( today , LocalTime.NOON , z ) ;
Calculate elapsed time either based in fractional seconds, or in whole calendar days.
Duration d = Duration.between( zdtTodayNoon , zdt ) ; // For a calculation based in whole seconds plus a fractional second in nanoseconds without regard for a calendar, just using generic 24-hour days.
Period p = Period.between( zdtTodayNoon , zdt ) ; // For a calculation based in whole days, for a number of years-months-days based on calendar dates.
If you insist on tracking by a count of milliseconds, call Duration::toMillis.
long millisecondsElapsed = d.toMillis() ; // Entire duration as a total number of milliseconds, ignoring any microseconds or nanos.
All of this has been covered many times already on Stack Overflow. You can learn more and see more examples by searching for these java.time class names.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
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….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I am extracting the date field from the sms table which returns the date as a time stamp,
but I wish to extract from the time stamp seprately
time of the day,
day of the week and
month of the year
I have read similar questions but none could help.
String date = cursor.getString(cursor.getColumnIndex("date"));
Long timestamp = Long.parseLong(date);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
Date finaldate = calendar.getTime();
String smsDate = finaldate.toString();
dateTextView.setText(smsDate);
int day= calendar.get(Calendar.DAY_OF_WEEK));
int month = calendar.get(Calendar.MONTH);
If you want to have the actual string value of month and the day, you can either use a switch to do that
Try the following,
String dayAsString = calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault());
String monthAsString = calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
Edit:
int hour12 = calendar.get(Calendar.HOUR); // 12
int hour24 = calendar.get(Calendar.HOUR_OF_DAY); //24
You can do calendar.MONTH, calendar.DAY and so.
you should use Joda Time:
http://www.joda.org/joda-time/
String date = cursor.getString(cursor.getColumnIndex("date"));
Long timestamp = Long.parseLong(date);
DateTime dateTime = new DateTime(timestamp);
int dayOfWeek = dateTime.getDayOfWeek();
int monthOfYear = dateTime1.getMonthOfYear();
tl;dr
Instant.ofEpochMilli( myCountOfMillis ) // Parse a count of milliseconds since first moment of 1970 in UTC.
.atZone( ZoneId.of( "Pacific/Auckland" ) ) // Instantiate a `ZonedDateTime` object, having adjusted from UTC into a particular time zone.
.getDayOfWeek() // Extract a `DayOfWeek` enum object.
.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) // Or Locale.US, Locale.ITALY, etc. to determine human language and cultural norms in generating a localized string to represent this day-of-week.
lundi
java.time
Modern approach uses the java.time classes.
Assuming your long integer is a count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z, instantiate a Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.ofEpochMilli( myCountOfMillis ) ;
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Apply your desired/expected time zone to the Instant to get a ZonedDateTime. Same moment, same point on the timeline, but with a different wall-clock time.
ZonedDateTime zdt = instant.atZone( z ) ;
Now you are in a position to interrogate for the parts of month, day-of-week, and time-of-day.
Month month = zdt.getMonth() ; // Get a `Month` enum object.
int m = zdt.getMonthValue() ; // Get an integer 1-12 for January-December.
DayOfWeek dow = zdt.getDayOfWeek() ; // Get a `DayOfWeek` enum object.
int dowNumber = zdt.getDayOfWeek().getValue() ; // Get a number for the day-of-week, 1-7 for Monday-Sunday per ISO 8601 standard.
String dowName = zdt.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Generate a localized string representing the name of this day-of-week.
LocalTime lt = zdt.toLocalTime() ; // Get a time-of-day object, without date, without time zone.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
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
Much 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, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
how to compare three date/time values in java?
Currently i use Date objects
I mean:
Date1 - today, 10:00PM
Date2 - tomorrow, 5:00AM
Date3 - current time
Is date3 between date1 and date2, respect date AND time?
date1.compareTo(date3) * date2.compareTo(date3) > 0
and
date1.after(date3) && date2.before(date3)
are not working.
I use this code in Android App, and if i set my time to 11.30AM, it still returns true for above conditions. If i use Time-objects and 2nd method, it doesn't recognise my time span is between 2 days.
Any idea?
EDIT: To make it exact, here is my current code. app is something like an alarm clock.
// Current Date/Time
Date now = Calendar.getInstance().getTime();
// Time when user goes to bed (current day)
Date sleep = new Date(now.getYear(), now.getMonth(), now.getDate(), Shours, Sminutes);
// Time when user wakes up (next day)
// Get Next Day's Date and set Time
Calendar wk = Calendar.getInstance();
wk.setTime(sleep);
wk.set(Calendar.HOUR_OF_DAY, Whours);
wk.set(Calendar.MINUTE, Wminutes);
// tomorrow
wk.add(Calendar.DATE, 1);
// and convert to date
Date wake = wk.getTime();
// Compare
if(now.after(sleep) && now.before(wake)) {
Log.d("uSleep", "Debug: Night time");
}
else {
Log.d("uSleep", "Debug: Day Time");
}
Maybe it's still too hard to understand. Image you go to bed at 10PM and you get up at 5AM. Now how to find out if you're sleeping by comparing your "go to bed"-time and you "get up"-time to the current time. I need to use "tomorrow" for your "get up"-time, otherwise java seems to compare all times for the same day, which is impossible.
tl;dr
Interval.of(
start ,
stop
).contains(
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
.toInstant()
)
Details
The question is confusing, but seems to be…
How do I tell if a particular moment occurs within a span of time?
java.time
I mean: Date1 - today, 10:00PM Date2 - tomorrow, 5:00AM Date3 - current time
A time zone is crucial in determining “today” and “tomorrow”. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
To get the same date with another time-of-day, extract LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone. Specify desired time-of-day with LocalTime. Combine with ZoneId to get a ZonedDateTime.
LocalDate today = now.toLocalDate() ;
LocalTime tenPm = LocalTime.of( 22 , 0 ) ; // 10 PM is 22:00.
ZonedDateTime tenPmToday = ZonedDateTime.of( today , tenPm , z ) ;
To get tomorrow, add one day to today's date.
LocalDate tomorrow = ld.plusDays( 1 ) ;
LocalTime fiveAm = LocalTime.of( 5 , 0 ) ;
ZonedDateTime fiveAmTomorrow = ZonedDateTime.of( tomorrow ,fiveAm , z ) ;
Compare
To compare, call the isBefore, isEqual, and isAfter methods.
Boolean contains = ( ! now.isBefore( tenPmToday ) ) && now.isBefore( fiveAmTomorrow ) ;
Of course, now will always be before tomorrow, so I'm not sure of your intentions here.
org.threeten.extra.Interval
You may find the Interval class useful for this work, from the ThreeTen-Extra project listed below. This class stores a pair of Instant objects, and has some handy comparison methods such as contains.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Interval interval = Interval.of( tenPmToday.toInstant() , fiveAmTomorrow.toInstant() ) ;
Boolean contains = interval.contains( now.toInstant() ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
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
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
Update: the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
The best way is to use the Joda-Time library, rather than the java.util.Date/.Calendar classes which are notoriously troublesome, confusing, and flawed.
Span Of Time
In Joda-Time you can represent a span of time in three ways: Interval, Period, and Duration. In this case, we need Interval, defined by a pair of specific points in the timeline, with the half-open [) approach where the beginning is inclusive and the ending exclusive.
The pair of specific points, as well as the current moment now, are all represented by the DateTime class. Unlike a java.util.Date, a DateTime knows its own assigned time zone. If unspecified, the JVM’s current default time zone will be applied. So generally better to specify.
Example Code
Some example code using Joda-Time 2.5.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zone );
DateTime bedtime = now.withTime( 22, 0, 0, 0 ); // Today’s bedtime. May be past, future, or this very moment now.
DateTime risetime = bedtime.plusHours( 7 ); // 05:00 next morning.
Interval sleepInterval = new Interval( bedtime, risetime );
boolean asleep = sleepInterval.contains( now ); // Half-Open "[)" comparison, beginning is inclusive, ending exclusive.
Here is my problem with time stamp:
in MySql data base there is a column name creation_date with data type timestamp
the value in the column is 2014-07-04 17:35:07.0
when I am trying to convert it to millisecond using java code, it is showing different behavior
For example
if I fetch it using hibernate and print timestamp.getTime() it is showing 1404484507000
but while doing
Timestamp t=new Timestamp(2014, 7, 4, 17, 35, 7, 0);
System.out.println("t.getTime() - "+t.getTime());
it is showing 61365297907000
What's going wrong here.
Did you read the documentation for the (deprecated) constructor you're calling? In particular:
year - the year minus 1900
month - 0 to 11
I'd strongly advise you not to call that constructor to start with. If you're using Java 8, use java.time.Instant and then java.sql.Timestamp.fromInstant.
Otherwise, you could call the constructor taking a long (number of milliseconds) and then set the nanos part separately.
Note that a value of 1404484507000 represents 14:35:07 UTC, so presumably your database is performing a time zone conversion.
tl;dr
From database.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Most databases including MySQL store a moment in a column of a data type akin to the SQL-standard `TIMESTAMP WITH TIME ZONE` as UTC. So retrieve as a `OffsetDateTime` object, expecting its zone to be set to UTC.
ZonedDateTime zdt = odt.atZoneSameInstant( ZoneId.of( "Pacific/Auckland" ) ) ; // Adjust into any time zone you desire. Same moment, different wall-clock time.
To database.
myPreparedStatement.setObject( // As of JDBC 4.2, exchange java.time objects with your database, not mere integers or strings.
… ,
ZonedDateTime.of(
2014 , 7 , 4 ,
17 , 35 , 7 , 0 ,
ZoneId.of( "Africa/Tunis" ) // Specify the time zone giving context to that date and time – where on earth did you mean 5 PM?
)
.toOffsetDateTime() // Adjust from that zone to UTC.
.withOffsetSameInstant(
ZoneOffset.UTC
)
) ;
java.time
The modern solution uses java.time classes.
LocalDate ld = LocalDate.of( 2014 , Month.JULY , 4 ) ; // Or use integer `7` for July, 1-12 for January-December.
LocalTime lt = LocalTime.of( 17 , 35 , 7 );
To determine a moment, you need more than a date and time-of-day. You need a time zone to provide context. Do you mean 5 PM in Japan, or 5 PM in France, or 5 PM in Québec? Those would be any of three different moments.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Adjust from that zone to UTC.
OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ;
As of JDBC 4.2 we can directly exchange java.time objects with a database.
myPreparedStatement.setObject( … , odt ) ;
And retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Notice that at no point did we require the integer count from epoch reference. We used smart objects rather than dumb integers or strings.
As for Hibernate, I an not a user, but I do know it has been updated to work with the java.time classes.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
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….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
MySQL uses a different Date format than Java does.
You can conver it from the ResultSet, using the getTime and getDate functions:
String query = "SELECT date FROM bean";
[...]
bean.setDate(toJavaDate(resultSet.getDate(1), resultSet.getTime(1)));
Where the toJavaDate code is:
public java.util.Date toJavaDate(java.sql.Date sqlDate, java.sql.Time sqlTime){
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.YEAR, sqlDate.getYear() + 1900);
calendar.set(Calendar.MONTH, sqlDate.getMonth());
calendar.set(Calendar.DAY_OF_MONTH, sqlDate.getDate());
calendar.set(Calendar.HOUR_OF_DAY, sqlTime.getHours());
calendar.set(Calendar.MINUTE, sqlTime.getMinutes());
calendar.set(Calendar.SECOND, sqlTime.getSeconds());
return calendar.getTime();
}
The reverse operation, in order to save a new Date at the MySQL table:
String query = "UPDATE bean SET date = '" + toSqlDate(bean.getDate());
Where toSqlDate is:
public String toSqlDate(java.util.Date javaDate){
String sqlDate = (javaDate.getYear()+1900)+"-"+javaDate.getMonth()+"-"+javaDate.getDate()+" "
+javaDate.getHours()+":"+javaDate.getMinutes()+":"+javaDate.getSeconds();
return sqlDate;
}
Now you can recheck the milliseconds:
long milliseconds = date.getTime();
I am finding the current time using Date date3 = Calendar.getInstance().getTime();
This gives me Thu Oct 25 11:42:22 IST 2012
Now I want my Date to be in the format 2012.10.25 and that too as a Date object and not a string.
I tried using the below code
DateFormat df = new SimpleDateFormat("yyyy.MM.dd");
Date startDate = df.parse(c_date1);
But when I finally use System.out.println(startDate.toString()); it again gives me
Thu Oct 25 00:00:00 IST 2012. that is practically because the toString() function has been implemented in a way to show this format.
So is there any other way to get the date as 2012.10.25 and that too as the Date format. Date object is required because it is to be saved in db as a date field.
you need to use df.format(Date) method to get date in required format
Date date3 = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
System.out.println(df.format(date3));
Date date3 = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
java.sql.Date date = null;
try {
date =new java.sql.Date(df.parse(df.format(date3)).getTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(date);
tl;dr
Avoid terrible legacy date-time classes (Date, SimpleDateFormat). Use only the modern java.time classes.
LocalDate.now( // Instantiate a date-only object, without time-of-day and without time zone.
ZoneId.of( "India/Kolkata" ) // Capture the current date, “today”, as seen by the people in a certain region (a time zone). For any given moment, the date varies around the globe by zone.
)
.format( // Generate a String whose text represents the date-time value of our `LocalDate` object.
DateTimeFormatter.ofPattern( "uuuu.MM.dd" ) // Specify your desired formatting pattern.
)
2012.10.25
To insert the date-only value for the current date into your database:
myPreparedStatement.setObject(
… ,
LocalDate.now( ZoneId.of( "India/Kolkata" ) )
) ;
Confusing date-time value with a String
Date-time values do not have a “format”. Only strings have a format. Do not conflate the two. A date-time object can be instantiated by parsing a String. And a date-time object can generate a String to represent its value textually. But the date-time object and such strings remain separate and distinct.
it again gives me Thu Oct 25 00:00:00 IST 2012. that is practically because the toString() function has been implemented in a way to show this format.
No, the toString method does not “show” this format. That wording implies the format lives within the Date object. But the format does not live inside the Date object – the Date has no “format” at all. The toString method generates a String whose characters are arranged into this format.
Confusing date-only with date-time
You seem to interesting in a date-only values, without a time-of-day and without a time zone. If so, use the LocalDate class.
Create a LocalDate object for your desired value by parsing a string. Easiest to use the standard ISO 8601 format used by default in the java.time classes: YYYY-MM-DD.
String input = "2012-10-25" ;
LocalDate ld = LocalDate.parse( input ) ; // No need to specify a formatting pattern, as ISO 8601 format used by default.
Your input string is in a non-standard format. Happens to be the same year-month-day order, so I would just replace the FULL STOP dots with hyphens.
String input = "2012.10.25".replace( "." , "-" ) ; // Convert from custom format to standard ISO 8601 format.
LocalDate ld = LocalDate.parse( input ) ; // No need to specify a formatting pattern, as ISO 8601 format used by default.
Or specify a formatting pattern.
String input = "2012.10.25" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu.MM.dd" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
Use that same formatter object to generate a string.
String output = ld.format( f ) ; // Generate a string in this custom format.
Current date
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Database
As of JDBC 4.2 and later, we can directly exchange java.time objects with a database.
If storing this LocalDate object to a SQL-standard DATE column:
myPreparedStatment.setObject( … , ld ) ;
And retrieval:
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
If storing to a SQL-standard TIMESTAMP WITH TIME ZONE column, we need a date-time value rather than our date-only value. Perhaps you want to use the first moment of the day on that date? If so, let java.time determine that first moment. Do not assume 00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at another time such as 01:00.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // First moment of the day for that date for the people in India.
Most databases store zoned date-time moments by adjusting into UTC. Your JDBC driver and database may do that for you, or you can extract a UTC value (Instant) from your ZonedDateTime.
Instant instant = zdt.toInstant() ; // Adjust from zoned time to UTC time.
myPreparedStatment.setObject( … , instant ) ;
And retrieval:
Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
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
Much 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….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Date object do not have any format. i.e. you can not convert any Date object into perticular format. Becuase it has its own to string format which will return when you print any date. You can convert any string format only.
You can convert or construct any Date Object from date string of the specific format. but that date object will not be in a specific format.
Your question is just like asking:
I have an int variable of value 1234567, and I want it to store as "1,234,567" in that variable.
It is simply not reasonable.
How a value is stored, is nothing to do with how the value is presented.
If you want to save a date in db in given date format the you can use
DateFormat df = new SimpleDateFormat("yyyy.MM.dd");
Date date3 = Calendar.getInstance().getTime();
String startDate = df.format(date3);
try {
java.sql.Date date = new java.sql.Date(df.parse(startDate).getTime());
System.out.println(date);
} catch (ParseException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
It's very simple
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
format.parse(dateObject.toString());