I have a date in Integer format(YYYYMMDD). And a start_time as a String (HH:mm 24 hour system). and a time_duration in hours as a double.
int date = 20140214;
String start_time = "14:30";
double duration = 50.30;
I want to use these 3 values and create 2 Java Date Objects. One is start_date and one is end_date. They should be in the format YYYY-MM-DD HH:mm.
And then after I get 2 data Strings like YYYY-MM-DD HH:mm. how can I obtain those previous variables. date, start_time, duration.
This is my attempt.
public void solve() throws IOException {
int date = 20140214;
String start_time = "14:30";
double duration = 24.50;
String startDate = "";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
startDate = getDate(date) + " " + start_time;
try {
Date start_Date = df.parse(startDate);
Date end_Date = new Date(start_Date.getTime()+(int)(duration*3600*1000));
System.out.println(df.format(start_Date));
System.out.println(df.format(end_Date));
} catch (ParseException ex) {
}
}
public String getDate(int dateInt) {
String date = "";
String dateIntString = String.valueOf(dateInt);
date = date + dateIntString.substring(0, 4) + "-";
date = date + dateIntString.substring(4, 6) + "-";
date = date + dateIntString.substring(6, 8);
return date;
}
Is there any easy way to do it. ? Or some built-in capabilities I can use other than those I have used ?
Strange Data Types For Date-Time
Using:
An int to represent the digits of a calendar date
A string to represent time-of-day digits
A double to represent a duration of fractional hours
…are all unusual approaches. Probably not the wisest choices in handling date-time values.
Avoid java.util.Date/Calendar
Know that the bundled classes java.util.Date and .Calendar are notoriously troublesome and should be avoided. Use either Joda-Time or the new java.time.* package (Tutorial) in Java 8. And get familiar with the handy ISO 8601 standard.
Time Zone
Your question and example ignore the crucial issue of time zone. Handling date-time data without time zone is like handling text files without knowing their character encoding. Not good.
Use proper time zone names to create time zone object. Avoid the non-standard 3-letter codes.
Joda-Time
In Joda-Time, a DateTime object is similar to a java.util.Date object but actually knows its own assigned time zone.
Joda-Time offers three classes for representing spans of time: Period, Duration, and Interval.
The Interval class uses the "Half-Open" approach, where the beginning is inclusive and the ending is exclusive. This approach works well for handling spans of time and comparisons. Look for the handy contains, abuts, overlap, and gap methods.
int dateInput = 20140214;
String start_timeInput = "14:30";
double durationInput = 50.30;
// Clean up these inputs.
String datePortion = Integer.toString( dateInput );
String input = datePortion + " " + start_timeInput;
DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "yyyyMMdd HH:mm");
// Specify the time zone this date-time represents.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Or, DateTimeZone.UTC
DateTime dateTime = formatterInput.withZone( timeZone ).parseDateTime( input );
// Convert fractional hours to milliseconds, then milliseconds to a Duration object.
long millis = ( 60L * 60L * (long)(1000L * durationInput) ); // 1 hour = 60 minutes * 60 seconds * 1000 milliseconds.
Duration duration = new Duration( millis );
Interval interval = new Interval( dateTime, duration );
DateTimeFormatter formatterOutput = DateTimeFormat.forStyle( "MM" ).withLocale( Locale.FRANCE );
String description = "De " + formatterOutput.print( interval.getStart() ) + " à " + formatterOutput.print( interval.getEnd() );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "duration: " + duration ); // Format: PnYnMnDTnHnMnS (from ISO 8601)
System.out.println( "interval: " + interval ); // Format: <start>/<end> (from ISO 8601)
System.out.println( "description: " + description );
When run…
input: 20140214 14:30
dateTime: 2014-02-14T14:30:00.000+01:00
duration: PT181080S
interval: 2014-02-14T14:30:00.000+01:00/2014-02-16T16:48:00.000+01:00
description: De 14 févr. 2014 14:30:00 à 16 févr. 2014 16:48:00
You have very many representations of date.
When in doubt, I usually head for getting to unix standard time (milliseconds since 1970) as soon as possible.
In this case it would be to convert the Integer date to a String, read out the four first as a year, two digits as month and the last two as day day, and then do the similar thing for the 24h time, and create a java.util.Date from this like so:
SimpleDateFormat dateParser=new SimpleDateFormat("yyyyMMdd HH:mm"); //please double check the syntax for this guy...
String yyyyMmDd = date.toString();
String fullDate = yyyyMmDd + " " + start_time;
java.util.Date startDate = dateParser.parse(fullDate);
long startTimeInMillis = startDate.getTime();
final long MILLISECONDS_PER_HOUR = 1000*60*60;
long durationInMillis = (long)duration*MILLISECONDS_PER_HOUR;
java.util.Date endDate = new java.util.Date(startTimeInMillis + durationInMillis);
Don't miss Joda time or Java 8 new, finally improved date handling named java.time.
you can write like
int date = 20140214;
String s=""+date;
Date date = new SimpleDateFormat("yyyyMMdd").parse(s);
Related
I have to find out number of days between a given Time and current time. Given time is in ISO format and one example is "2021-01-14 16:23:46.217-06:00".
I have tried it using "java.text.SimpleDateFormat" but it's not giving me accurate results.
In Below Given date, for today's time I am getting output as "633" Days which isn't correct. somehow after parsing it is taking date as "21 december 2020" which isn't correct
String TIMESTAMP_FORMAT = "YYYY-MM-DD hh:mm:ss.s-hh:mm" ;
int noOfDays = Utility.getTimeDifferenceInDays("2021-01-14 16:23:46.217-06:00", TIMESTAMP_FORMAT);
public static int getTimeDifferenceInDays(String timestamp, String TIMESTAMP_FORMAT) {
DateFormat df = new SimpleDateFormat(TIMESTAMP_FORMAT);
try {
Date date = df.parse(timestamp);
long timeDifference = (System.currentTimeMillis() - date.getTime());
return (int) (timeDifference / (1000*60*60*24));
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
Looking for a better solution which gives me correct number of days. Thanks
Use java.time API
Classes Date and SimpleDateFormat are legacy.
Since Java 8 (which was released 10 years ago) we have a new Time API, represented by classes from the java.time package.
To parse and format the data, you can use DateTimeFormatter. An instance of DateTimeFormatter can be obtained via static method ofPattern(), or using DateTimeFormatterBuilder.
ofPattern():
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSXXX");
DateTimeFormatterBuilder:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss.") // main date-time part
.appendValue(ChronoField.MILLI_OF_SECOND, 3) // fraction part of second
.appendOffset("+HH:MM", "+00:00") // can be substituted with appendPattern("zzz") or appendPattern("XXX")
.toFormatter();
The string "2021-01-14 16:23:46.217-06:00", which you've provided as an example, contains date-time information and UTC offset. Such data can be represented by OffsetDateTime.
To get the number of days between two temporal objects, you can use ChronoUnit.between() as #MC Emperor has mentioned in the comments.
That's how the whole code might look like:
String toParse = "2021-01-14 16:23:46.217-06:00";
OffsetDateTime dateTime = OffsetDateTime.parse(toParse, formatter);
System.out.println("parsed date-time: " + dateTime);
Instant now = Instant.now();
long days = ChronoUnit.DAYS.between(dateTime.toInstant(), now);
System.out.println("days: " + days);
Output:
parsed date-time: 2021-01-14T16:23:46.217-06:00
days: 615
Note that since in this case you need only difference in days between the current date instead of OffsetDateTime you can use LocalDateTime, UTC offset would be ignored while parsing a string. If you decide to do so, then the second argument passed to ChronoUnit.between() should be also of type LocalDateTime.
I want to convert the given HH:mm from UTC to different time zones.
String myDateString = "02:30";
LocalTime localTime = LocalTime.parse(myDateString, DateTimeFormatter.ofPattern("HH:mm"));
int hour = localTime.get(ChronoField.CLOCK_HOUR_OF_DAY);
int minute = localTime.get(ChronoField.MINUTE_OF_HOUR);
int second = localTime.get(ChronoField.SECOND_OF_MINUTE);
System.out.println("UTC Time is "+ hour + ":" + minute);
Calendar pstTime = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"));
hour = pstTime.get(hour);
minute = pstTime.get(minute);
getting error with this. any help appreciated.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
30
As already said, a time zone without day part misses information considering DST.
So it is:
String myDateString = "02:30";
LocalTime localTime = LocalTime.parse(myDateString,
DateTimeFormatter.ofPattern("HH:mm"));
LocalDateTime localDateTime = localTime.atDate(LocalDate.now());
System.out.println("localDateTime: " + localDateTime);
ZonedDateTime zonedDateTimeUTC = localDateTime.atZone(ZoneId.of("UTC"));
System.out.println("zonedDateTimeUTC: " + zonedDateTimeUTC);
ZonedDateTime zonedDateTimePST = zonedDateTimeUTC.withZoneSameInstant(
ZoneId.of("America/Los_Angeles"));
System.out.println("zonedDateTimePST: " + zonedDateTimePST);
int hour = zonedDateTimePST.getHour();
int minute = zonedDateTimePST.getMinute();
int second = zonedDateTimePST.getSecond();
There is no need for the old Calendar class.
I think you should specify date too. For that problem you can use this block of code
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
.ofPattern("MM/dd/yyyy'T'HH:mm z");
String inputValue = "08/03/2020T15:20 UTC";
ZonedDateTime zdtInstanceAtOffset = ZonedDateTime.parse(inputValue, DATE_TIME_FORMATTER);
ZonedDateTime zonedDateTime = zdtInstanceAtOffset.withZoneSameInstant(ZoneId.of("America/Los_Angeles"));
System.out.println(zonedDateTime);
Without a date, you can convert a time, given for one timezone, to another timezone only by adding/subtracting the time difference between the source timezone and the target timezone to/from the given time.
The problem with this approach is, that the time difference between timezones is not constant over the year, when it is identified by "region/location" (like "America/Los Angeles"). If you use "EST" or "GMT" or "CET" (sometimes referred to as "zone times") instead, the differences would be stable – but you are still inaccurate: several timezones will have two zone times, depending on the time in the year …
You can use the java.time.ZonedDateTime class for this and the method withZoneSameInstant(ZoneId zone) which returns a copy of the datetime in the specified zone.
Here is an example if your input time is in UTC timezone. To change the zone of the input time change Zone inputZone to ZoneId.of("<your timezone>");
public static void main(String[] args) {
String timeString = "02:30";
// Change this to the zone of the input time
ZoneId inputZone = ZoneId.of("UTC");
// Parse your input into time
LocalTime time = LocalTime.parse(timeString);
// Add current date to the time, you can add custom date using LocalDate.of(int year, int month, int dayOfMonth)
LocalDateTime localDateTime = time.atDate(LocalDate.now());
// Declare zoned date time with input zone specified
ZonedDateTime zonedDateTime = localDateTime.atZone(inputZone);
// Declare zones you will use
ZoneId myZone = ZoneId.systemDefault();
ZoneId utcZone = ZoneId.of("UTC");
ZoneId nyZone = ZoneId.of("America/New_York");
ZoneId tokyoZone = ZoneId.of("Asia/Tokyo");
// Get times in different timezones
ZonedDateTime myDateTime = zonedDateTime.withZoneSameInstant(myZone);
ZonedDateTime utcDateTime = zonedDateTime.withZoneSameInstant(utcZone);
ZonedDateTime nyDateTime = zonedDateTime.withZoneSameInstant(nyZone);
ZonedDateTime tokyoDateTime = zonedDateTime.withZoneSameInstant(tokyoZone);
// Print the times in different timezones
System.out.println("My Timezone: " + myDateTime);
System.out.println("UTC: " + utcDateTime);
System.out.println("NY: " + nyDateTime);
System.out.println("Tokyo: " + tokyoDateTime);
// Print without the offset
System.out.println("My Timezone: " + myDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println("UTC: " + utcDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println("NY: " + nyDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println("Tokyo: " + tokyoDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
This code will generate the following output:
My Timezone: 2020-03-11T03:30+01:00[Europe/Zagreb]
UTC: 2020-03-11T02:30Z[UTC]
NY: 2020-03-10T22:30-04:00[America/New_York]
Tokyo: 2020-03-11T11:30+09:00[Asia/Tokyo]
My Timezone: 2020-03-11T03:30:00
UTC: 2020-03-11T02:30:00
NY: 2020-03-10T22:30:00
Tokyo: 2020-03-11T11:30:00
I want to query SQLite table and get records where the time field (which is a String representing long time in millis) is in the range of tomorrow from querying time.
I also have a field which holds the record date time like this:
dd/MM/yyyy, HH:mm:ss
How would you recommend implementing this?
As per your comment you are open to modify the schema for better performance. So it is better to save time as long (unix timestamp) in database and having an index on that. Once that is done you can simply get tomorrows date at 00:00 in local time zone and convert it to unix timestamp and query based on that. Here is how you can get tomorrows timestamp at 00:00,
public static long getTimeStampAt0000(long timestamp) {
Calendar givenDate = Calendar.getInstance();
givenDate.setTimeInMillis(timestamp);
givenDate.set(Calendar.HOUR_OF_DAY, 0);
givenDate.set(Calendar.MINUTE, 0);
givenDate.set(Calendar.SECOND, 0);
givenDate.set(Calendar.MILLISECOND, 0);
return givenDate.getTimeInMillis();
}
public static long getTimeStampAt0000ForTomorrow() {
long now = System.currentTimeMillis();
long nowAt0000 = getTimeStampAt0000(now);
if (now == nowAt0000) {
// if being queried at 00:00, we are assuming we want same or else we can just remove
// this condition
return nowAt0000;
} else {
return nowAt0000 + 86400000;
}
}
The SQLite doc says that it stores as:
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Are you certain you have milliseconds since epoch or seconds?
The bundled java.util.Date and Calendar classes are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time.* package in Java 8.
Note that both java.util.Date and Joda-Time DateTime use milliseconds since epoch, while the new java.time uses nanoseconds. Multiply by 1000L as needed.
When talking about "today" and "tomorrow" with a date-time, you must specify a time zone. The beginning and ending of a day depends on time zone.
// Simulate input.
long millis = DateTime.now().getMillis();
// Use a proper time zone name rather than 3-letter codes.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" ); // Formerly known as Calcutta, India.
DateTime dateTime = new DateTime( millis, timeZone );
DateTime aDayLater = dateTime.plusDays( 1 );
// "Tomorrow" is a span of time.
DateTime startOfToday = new DateTime( timeZone ).withTimeAtStartOfDay();
// Interval comparison is done in "half-open" approach where beginning is inclusive and ending is exclusive.
Interval tomorrow = new Interval( startOfToday.plusDays( 1 ), startOfToday.plusDays( 2 ) );
boolean isDateTimeOccurringTomorrow = tomorrow.contains( dateTime );
boolean isADayLaterOccurringTomorrow = tomorrow.contains( aDayLater );
Dump to console…
System.out.println( "millis: " + millis );
System.out.println( "dateTime: " + dateTime );
System.out.println( "aDayLater: " + aDayLater );
System.out.println( "startOfToday: " + startOfToday );
System.out.println( "tomorrow: " + tomorrow );
System.out.println( "isDateTimeOccurringTomorrow: " + isDateTimeOccurringTomorrow );
System.out.println( "isADayLaterOccurringTomorrow: " + isADayLaterOccurringTomorrow );
When run…
millis: 1392883763016
dateTime: 2014-02-20T13:39:23.016+05:30
aDayLater: 2014-02-21T13:39:23.016+05:30
startOfToday: 2014-02-20T00:00:00.000+05:30
tomorrow: 2014-02-21T00:00:00.000+05:30/2014-02-22T00:00:00.000+05:30
isDateTimeOccurringTomorrow: false
isADayLaterOccurringTomorrow: true
I want convert the Date in long. But the hours are incorrectly calculated at pc. On Android emulator is the Time correct calculated(on emulator is UTC time). Please help
String time = "15:54";
Date date = new Date();
date.setHours(Integer.parseInt(time.substring(0, 2)));
long Hours = (date.getTime() / (1000 * 60 * 60)) % 24;
System.out.print(Hours); // 14
System.out.print("\n" + date.getHours()); // 15
When you are setting the hours to Date, java.util.Date object is independent of the concept of TimeZone. Per its javadoc here,
Although the Date class is intended to reflect coordinated universal
time (UTC), it may not do so exactly, depending on the host
environment of the Java Virtual Machine.
Hence, when you set your hours to 15, date interprets your own timezone and sets the hours to it. If there is a difference in UTC (the result you expect) and your current timezone, that difference is being reflected in your case above (14 vs 15).
To solve it, 1 option is to explicitly bring your own timezone to UTC and match the expected results:
String time = "15:54";
Date date = new Date();
java.util.TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // ADDED THIS LINE
date.setHours(Integer.parseInt(time.substring(0, 2)));
long hours = (date.getTime() / (60 * 60 * 1000)) % 24;
System.out.print(hours); // NOW THIS GIVES 15
System.out.print("\n" + date.getHours()); // 15
The other option would to use Calendar class (if not jodatime) in case you want to accurately interpret the TimeZone related results.
Your question is not clear.
This kind of date-time work is much easier with the Joda-Time library.
Relying on the default time zone is troublesome. Instead, specify your time zone. It sounds like in your case the desired hour "15" is in UTC/GMT (no time zone offset). So, specify UTC.
What did you mean by "convert the Date in long"? Perhaps you meant get the milliseconds-since-epoch stored inside the Date (and in Joda-Time DateTime).
DateTime now = new DateTime( DateTimeZone.UTC );
DateTime fifteen = now.withHourOfDay( 15 );
Dump to console…
System.out.println( "now: " + now );
System.out.println( "fifteen: " + fifteen );
System.out.println( "fifteen in millis: " + fifteen.getMillis() );
System.out.println( "fifteen's hour-of-day: " + fifteen.getHourOfDay() );
When run…
now: 2014-02-14T12:43:00.836Z
fifteen: 2014-02-14T15:43:00.836Z
fifteen in millis: 1392392580836
fifteen's hour-of-day: 15
If try to call method:
private static String TIME_FORMAT = "HH:mm Z";
public static void TestDate( String time_ ) throws ParseException
{
SimpleDateFormat format = new SimpleDateFormat( TIME_FORMAT );
Date date = format.parse( time_ );
long hours = (date.getTime() / (1000 * 60 * 60)) % 24;
System.out.println( "The value 'hours' for '" + time_ + "' is '" + Long.toString( hours ) + "'" );
}
with "15:54 UTC", output wil be:
The value 'hours' for '15:54 UTC' is '15'
This question already has answers here:
Java 8 Date and Time: parse ISO 8601 string without colon in offset [duplicate]
(4 answers)
Closed 3 years ago.
StrDate = "2011-07-19T18:23:20+0000";
How can I get an epoch time for the above date format in android
also I would like to know how to convert a epoch time to the above date format.
I would appreciate a direct answer with an example.
Example code using Joda-Time 2.3.
Unix time is number of seconds since beginning of 1970 in UTC/GMT.
How can I get an epoch time for the above date format in android
DateTime dateTimeInUtc = new DateTime( "2011-07-19T18:23:20+0000", DateTimeZone.UTC );
long secondsSinceUnixEpoch = ( dateTimeInUtc.getMillis() / 1000 ); // Convert milliseconds to seconds.
…and…
how to convert a epoch time to the above date format.
String dateTimeAsString = new DateTime( secondsSinceUnixEpoch * 1000, DateTimeZone.UTC ).toString();
To dump those values to the console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc );
System.out.println( "secondsSinceUnixEpoch: " + secondsSinceUnixEpoch );
System.out.println( "dateTimeAsString: " + dateTimeAsString );
Bonus: Adjust to another time zone.
DateTime dateTimeMontréal = dateTimeInUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
You should use SimpleDateFormat. That class both supports formatting, and parsing.
Sample code:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ");
Date gmt = formatter.parse("2011-07-19T18:23:20+0000");
long millisecondsSinceEpoch0 = gmt.getTime();
String asString = formatter.format(gmt);
Note that a Date instance in Java, always represent milliseconds since epoch 0, in UTC/GMT, but it is printed in local time when you print it.
To answer your question a bit late but Joda-Time will be able to handle both in a simply and clean way.
Using Joda-Time
1.Epoch time to Date
Where date is your epoch time
DateTime dateTime = new DateTime(date*1000L);
System.out.println("Datetime ..." + dateTime);
Datetime from Epoch ...2014-08-01T13:00:00.000-04:00
2.Date to epoch
DateTime fromDate = new DateTime("2011-07-19T18:23:20+0000");
long epochTime = fromDate.getMillis();
System.out.println("Date is.." + fromDate + " epoch of date " + epochTime);
Date is..2011-07-19T14:23:20.000-04:00 epoch of date 1311099800000