I have a task in which i need to set hour, minute, meridian programmatically to Calendar object and need to display time in a format hh:mm a. Here below is my code so far.
Calendar calendar = (Calendar)dateNtime.clone();
calendar.set(Calendar.HOUR, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.AM_PM, 1);
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
String str = dateFormat.format(calendar.getTimeInMillis());
Where dateNTime is an existing calendar object which i have to use in constructing new one.
All is going fine except only a case while i set 12PM. it always format hh:mm a and results 12:00AM while it should be 12:00PM.
please help if anybody have a good experience with Calendar object and it's known issue or provide me if there is a good tutorial link.
The HOUR field is documented as:
Field number for get and set indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock (0 - 11).
So instead of setting it to 12, you should set it to 0.
Personally I'd just set the HOUR_OF_DAY field, adding 12 hours if you want to make it PM - and don't set the AM_PM field at all.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern API:
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
// timezone e.g. ZoneId.of("America/New_York")
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault())
.withHour(12)
.withMinute(0);
System.out.println(zdt);
// Get and display just time in default format
LocalTime time = zdt.toLocalTime();
System.out.println(time);
// Display just time in a custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
// Alternatively, dtf.format(time);
String formatted = dtf.format(zdt);
System.out.println(formatted);
}
}
Output:
2021-06-06T12:00:15.855986+01:00[Europe/London]
12:00:15.855986
12:00 PM
ONLINE DEMO
How to convert Calendar to java.time type?
Instant instant = calendar.toInstant();
// Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
// timezone e.g. ZoneId.of("America/New_York")
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
What if I need Calendar object from java.time type?
For any reason, if you need to convert this object of ZonedDateTime to an object of java.util.Calendar, you can do so as follows:
Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(zdt.toInstant()));
Learn more about java.time, the modern Date-Time API* from Trail: Date Time.
Sometimes, comments get deleted and therefore quoting below a valuable comment from Ole V.V.:
For a more accurate conversion to Calendar you may use
GregorianCalendar.from(zdt)
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Related
how to I convert date time to others time zone using java.
example : 11 June 2021 20:00 to 11 June 2021 06:00 PM
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date parsed = format.parse("2021-03-01 20:00");
*\\to//*
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm z");
Date parsed = format.parse("2021-03-01 06:00 PM");
like this
First of all you should use the new java 8 API for data and time, java.time, secondly you need to have a zone to convert to and from. Here I have assumed you want to use the zone of the device (and convert to GMT) as from and GMT as to.
String input = "2021-03-01 20:00";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneId.systemDefault());
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a").withZone(ZoneId.of("GMT"));
TemporalAccessor date = inputFormatter.parse(input);
String output = outputFormatter.format(date);
System.out.println(output);
Joakim Danielson is on to the right thing in his answer: use java.time, the modern Java date and time API, for your date and time work. My solution roughly follows the same overall pattern. There are some details I’d like to show you.
private static final DateTimeFormatter inputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
private static final DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a");
DateTimeFormatter is thread-safe so there’s no problem instantiating them only once even if they are used from different threads.
String input = "2021-03-01 20:00";
String output = LocalDateTime.parse(input, inputFormatter)
.atZone(ZoneId.systemDefault())
.withZoneSameInstant(ZoneOffset.UTC)
.format(outputFormatter);
System.out.println(output);
Output is the same as from Joakim’s code. In my time zone (Europe/Copenhagen) it is:
2021-03-01 7:00 PM
java.time lends itself well to a fluent writing style. Why not exploit it? Since conversion to a different time zone was the point, I prefer to make it explicit in the code. The withZoneSameInstant() call makes the conversion. And I prefer to parse into either LocalDateTime or ZonedDateTime rather than using the low-level TemporalAccessor interface directly. The documentation of the interface says:
This interface is a framework-level interface that should not be
widely used in application code. Instead, applications should create
and pass around instances of concrete types, such as LocalDate.
There are many reasons for this, part of which is that implementations
of this interface may be in calendar systems other than ISO. …
I need api 21 support. This is not available on api 21
Indeed java.time works nicely on Android API level 21.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of TemporalAccessor
Question: cannot resolve symbol 'java.time.LocalDate' error in android studio about using java.time on earlier Andoird
Question: Android - Date in API Level 21 [closed]
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
You must get your date format to a specific zone, as you have not mentioned in the post, i will give 1 sample below,
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yyyy-MM-dd HH:mm);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Now using this simpleDateFormat for your specific timezone, you can format the value.
The key to the solution is to get the zone offset between two date-times which you can calculate with Duration#between and then change the zone offset of the first date-time into that of the second one (which is equal to the hours and minutes part of the calculated duration.
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Given date-time strings
String strOne = "11 June 2021 20:00";
String strTwo = "11 June 2021 06:00 PM";
// Respective formatters
DateTimeFormatter dtfOne = DateTimeFormatter.ofPattern("dd MMMM uuuu HH:mm", Locale.ENGLISH);
DateTimeFormatter dtfTwo = DateTimeFormatter.ofPattern("dd MMMM uuuu hh:mm a", Locale.ENGLISH);
// Respective instances of LocalDateTime
LocalDateTime ldtOne = LocalDateTime.parse(strOne, dtfOne);
LocalDateTime ldtTwo = LocalDateTime.parse(strTwo, dtfTwo);
// Duration between the two date-times
Duration duration = Duration.between(ldtOne, ldtTwo);
int hours = duration.toHoursPart();
int minutes = duration.toMinutesPart();
// Zone offset with hours and minutes of the duration
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes(hours, minutes);
//
ZonedDateTime zdt = ldtOne.atZone(ZoneId.systemDefault()) // ZonedDateTime using JVM's time zone
.withZoneSameInstant(zoneOffset); // ZonedDateTime using the given zone offset
System.out.println(zdt);
String formatted = zdt.format(dtfTwo);// Format the given ZonedDateTime using the given formatter
System.out.println(formatted);
}
}
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
Note: If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I want to store a string into a databse (SQLite) for an Android App with the current time and date. For that purpose I am using SimpleDateFormat. Unfortunately it does not show the correct time when. I tried two options.
First Option (from SimpleDateFormat with TimeZone)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.getDefault());
sdf.format(new Date());
Second option (from Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST)
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'");
sdf2.setTimeZone(TimeZone.getTimeZone("CEST"));
In both cases the time is just wrong. It is not the local time that my laptop or phone is showing but the output time is 2 hours earlier. How can I change that? I would like to have the current time of Berlin (CEST) that is also shown on my computer. I appreciate every comment.
Use Europe/Berlin instead of CEST and you will get the expected result.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
sdf2.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println(sdf2.format(new Date()));
}
}
Output:
2020-09-27 18:38:04 +0200
A piece of advice:
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
// Default format
System.out.println(zdt);
// Some custom format
System.out.println(zdt.format(DateTimeFormatter.ofPattern("EEEE dd uuuu hh:mm:ss a z")));
}
}
Output:
2020-09-27T18:42:53.620168+02:00[Europe/Berlin]
Sunday 27 2020 06:42:53 pm CEST
The modern API will alert you whereas legacy API may failover:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("CEST"));
// ...
}
}
Output:
Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: CEST
at java.base/java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:279)
at java.base/java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:234)
at java.base/java.time.ZoneRegion.ofId(ZoneRegion.java:120)
at java.base/java.time.ZoneId.of(ZoneId.java:408)
at java.base/java.time.ZoneId.of(ZoneId.java:356)
at Main.main(Main.java:6)
As you can see, you get an exception in this case whereas SimpleDateFormat will give you undesirable result as shown below:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
sdf2.setTimeZone(TimeZone.getTimeZone("CEST"));
System.out.println(sdf2.format(new Date()));
}
}
Output:
2020-09-27 16:47:45 +0000
You might be wondering what this undesirable result refers to. The answer is: when SimpleDateFormat doesn't understand a time-zone, it failovers (defaults) to GMT (same as UTC) i.e. it has ignored CEST and applied GMT in this case (not a good feature IMHO 😊).
ISO 8601
Assuming that your SQLite hasn’t got a datetime datatype I recommend that you use ISO 8601 format, the international standard, for storing your date-times as strings to SQLite. Next, consider using java.time, the modern Java date and time API, for your date and time work. The two suggestions go nicely hand in hand. Common recommendations say to store date and time in UTC, but I understand that you prefer Europe/Berlin time.
ZoneId databaseTimeZone = ZoneId.of("Europe/Berlin");
ZonedDateTime now = ZonedDateTime.now(databaseTimeZone);
String databaseTime = now.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println(databaseTime);
Output from the above when running just now:
2020-09-27T15:54:21.53+02:00
I have on purpose included the offset from UTC in the string. This will allow anyone retrieving the string to convert the time to UTC or the time zone of their preference. If the user travels to India to see Taj Mahal and retrieves the data there, converting to India Standard Time is no problem. The offset also disambiguates times in the night in October when Berlin changes from summer time (DST) to standard time and the same clock times repeat. Times before the change will have offset +02:00, times after the change will have +01:00.
How can I change the format(?)
Edit: If you insist on your own format for information and human readability, build a formatter for that. The ZonedDateTime already has the time in your chosen time zone, so that time is also the one you will have when you format it:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z");
String databaseTime = now.format(formatter);
Now the result is:
2020-09-27 16:22:23 +0200
Further edit: Since human readability is the only requirement for that column, go all-in on that and use java’s predefined localized format, for example:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(Locale.GERMAN);
September 2020 19:06:03 MESZ
If it’s too long for you, use FormatStyle.MEDIUM instead.
Further further edit: And why? The question is whether 27. September 2020 19:06:03 MESZ is easier to read and understand correctly than 2020-09-27 16:22:23 +0200. You should make it as easy for yourself as you reasonably can. There is a point in including the offset, +0200, though, since it is unambiguous whereas a time zone abbreviation like MESZ is not guaranteed to be (many time zone abbreviations are ambiguous).
What went wrong in your code?
You are probably running your code on a computer with its time zone set to UTC (or some other time zone that is currently two hours behind Berlin time). In your second snippet you are trying to make up for this fact by setting the time zone of you formatter to CEST (Central European Summer Time). The way you are doing that is not what you want, and it also does not work. Both have to do with the fact that CEST is not a time zone. CEST is two hours ahead of UTC, and if it had worked, you would have got two hours ahead of UTC also during the standard time of year where Berlin is only 1 hour ahead of UTC, that is, the wrong time. Since CEST is not a time zone, TimeZone does not recognize it as a time zone. And this is as confusing as the TimeZone class is: instead of objecting, it tacitly gives you GMT, so you have got nowhere. I really recommend avoiding using that class. The correct time zone identifier for Berlin is Europe/Berlin, the one I am also using in my code. Time zone identifiers come in the region/city format.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
Well, i faced the same issue a week ago and I figured out that the problem is in the TimeZone settings
If you are getting the date as a string and you need to format it to another format use the code below
public String getCalendarDate(String inputDate){
Date date = getDateFromSource(inputDate);
SimpleDateFormat formatter = new SimpleDateFormat("EEEE, d MMMM yyyy", Locale.getDefault());
formatter.setTimeZone(TimeZone.getDefault());
return formatter.format(date);
}
Date getDateFromSource(String apiDate){
Date newFormattedDate = null;
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
newFormattedDate = parser.parse(apiDate);
} catch (ParseException e) {
e.printStackTrace();
}
return newFormattedDate;
}
In the getDateFromSource function change the date format to the source format, while in the getCalendarDate function, change the format to your required format.
If you already have the Date object, you can ignore the getDateFromSource function and put it directly in the second one
For those who use Kotlin this is the equivalent code
fun getCalendarDate(apiDate: String): String{
val date = getDateFromApi(apiDate)
val formatter = SimpleDateFormat("EEEE, d MMMM yyyy", Locale.getDefault())
formatter.timeZone = TimeZone.getDefault()
return formatter.format(date)
}
private fun getDateFromApi(apiDate: String) :Date{
val parser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH)
parser.timeZone = TimeZone.getTimeZone("UTC")
return parser.parse(apiDate)!!
}
I have two related questions.
Assume a program running in (British Standard Time)BST generates a date time value for current time in UTC (YYYY-MM-DDTHH:MM:SS.SSSZ) format.
Also assume current time in London is 2016-06-01 12:33:54.
If the current time given by the program is 2016-06-01T11:33:54.000Z , is the program wrong?
How is summertime offset for BST noted in the corresponding time format for YYYY-MM-DDTHH:MM:SS.SSSZ
I assume YYYY-MM-DDTHH:MM:SS+0001. Am I correct ?
Firstly please have a read of the iso8601 information. It's becoming more common place to deal with times in different time zones (e.g. server time zone and client time zone) and the standard is really useful.
In particular please read about UTC or "Zulu" time here.
The program is correct, since the London time is one hour ahead of "UTC" time in summer
The trailing 'Z' is a short notation for UTC (Zulu). You could also write "+00:00" instead of 'Z'. The SS.SSS refer to seconds and milliseconds - not related to the time zone. In devnull's comment he shows you how to apply an offset for summer.
Edit:
There's been some discussion in the comments about whether iso8601 timezone includes timezone or not, and whether timezone will in fact be printed out.
This depends completely on the date/time implementation. If we are using SimpleDateFormat then timezone is supported and will be printed.
Here's a code example to illustrate
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(new Date()));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(formatter.format(new Date()));
Output
2016-06-02T12:53:14.924Z
2016-06-02T13:53:14.925+01:00
Naturally, if you are using a different date/time library such as joda-time, then the implentation details will be different.
Edit: As #DerrylThomas pointed out with SimpleDateFormat wise to use lower case y for years - unless it's intended to use week year - explained in a bit of detail in another answer to a similar question https://stackoverflow.com/a/56911450.
if the current time given by the program is 2016-06-01T11:33:54.000Z ,
is the program wrong?
The format is correct and conforms to ISO 8601 but it does not represent Europe/London time. In London, in 2016, the DST started at Sunday, March 27, 1:00 am and ended at Sunday, October 30, 2:00 am and therefore a date-time representation for Europe/London during this time should have a timezone offset of +01:00 hours. The Z at the end specifies Zulu time which is UTC time and thus has a timezone offset of +00:00 hours. The same instant can be represented for Europe/London as 2016-06-01T12:33:54+01:00.
java.time
The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API* .
Even Joda-Time should not be used anymore. Notice the following note at the Home Page of Joda-Time
Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).
java.time API is based on ISO 8601 and the date-time string, 2016-06-01T11:33:54.000Z can be parsed into java.time.ZonedDateTime and java.time.OffsetDateTime without needing a date-time parsing/formatting type.
Demo:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.parse("2016-06-01T11:33:54.000Z");
System.out.println(zdt);
ZoneId zoneId = ZoneId.of("Europe/London");
ZonedDateTime zdtInLondon = zdt.withZoneSameInstant(zoneId);
System.out.println(zdtInLondon);
}
}
Output:
2016-06-01T11:33:54Z
2016-06-01T12:33:54+01:00[Europe/London]
How to deal with Daylight Saving Time (DST)?
As mentioned earlier, the date-time string, 2016-06-01T11:33:54.000Z can also be parsed into java.time.OffsetDateTime without needing a date-time parsing/formatting type. However, OffsetDateTime has been designed to deal with a fixed timezone offset whereas ZonedDateTime has been designed to deal with a timezone and thus it take care of DST automatically. You can convert a ZonedDateTime to OffsetDateTime using ZonedDateTime#toOffsetDateTime if required.
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS z", Locale.ENGLISH);
String strDateTime = "2016-03-01T11:33:54.000 Europe/London";
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
strDateTime = "2016-06-01T11:33:54.000 Europe/London";
zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
Output:
2016-03-01T11:33:54Z[Europe/London]
2016-06-01T11:33:54+01:00[Europe/London]
Notice how the timezone offset has automatically changed from Z to 01:00 to reflect DST change. On the other hand,
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2016-03-01T11:33:54.000+01:00";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
strDateTime = "2016-06-01T11:33:54.000+01:00";
odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
}
}
Output:
2016-03-01T11:33:54+01:00
2016-06-01T11:33:54+01:00
In this case, you do not talk about a timezone (e.g. Europe/London); rather, you talk about a fixed timezone offset of +01:00 hours.
Learn more about the modern date-time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I want to get the previous day (24 hours) from the current time.
e.g if current time is Date currentTime = new Date();
2011-04-25 12:15:31:562 GMT
How to determine time i.e
2011-04-24 12:15:31:562 GMT
You can do that using Calendar class:
Calendar cal = Calendar.getInstance();
cal.setTime ( date ); // convert your date to Calendar object
int daysToDecrement = -1;
cal.add(Calendar.DATE, daysToDecrement);
date = cal.getTime(); // again get back your date object
I would suggest you use Joda Time to start with, which is a much nicer API. Then you can use:
DateTime yesterday = new DateTime().minusDays(1);
Note that "this time yesterday" isn't always 24 hours ago though... you need to think about time zones etc. You may want to use LocalDateTime or Instant instead of DateTime.
please checkout this here:
Java Date vs Calendar
Calendar cal=Calendar.getInstance();
cal.setTime(date); //not sure if date.getTime() is needed here
cal.add(Calendar.DAY_OF_MONTH, -1);
Date newDate = cal.getTime();
24 hours and 1 day are not the same thing. But you do both using Calendar:
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, -1);
Date d = c.getTime();
If you are going back 24 hours, you would use Calendar.HOUR_OF_DAY
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.Instant;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
System.out.println("Now: " + now);
Instant yesterday = now.minus(1, ChronoUnit.DAYS);
System.out.println("Yesterday: " + yesterday);
}
}
Output of a sample run:
Now: 2021-07-16T20:40:24.402592Z
Yesterday: 2021-07-15T20:40:24.402592Z
ONLINE DEMO
For any reason, if you need to convert this object of Instant to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I'm trying to convert a long timestamp that is UTC to Eastern Standard Time and am totally lost. Any hints would be great!
Thanks,
R
Try this:
Date estTime = new Date(utcTime.getTime() + TimeZone.getTimeZone("EST").getRawOffset());
Where utcTime is Date object of UTC time (if you already have the long value - just use it)
final Calendar c = Calendar.getInstance(TimeZone.getTimeZone("EST"));
c.setTimeInMillis(longTime);
Where longTime is the number of milliseconds since the epoch in UTC time. You can then use the methods of the Calendar class to get the various components of the date/time.
rd42, Can you give me a little more context on this?
You say you have a "UTC timestamp". Is this stored in a database? Is it a string?
I might be able to provide you more of an answer if you can give the context you're trying to work this in.
Ok for clarity's sake what you're saying is that you have a long value that represents a timestamp in UTC.
So in that case what you're going to want to do is the following.
import java.util.Calendar;
import java.util.TimeZone;
TimeZone utcTZ= TimeZone.getTimeZone("UTC");
Calendar utcCal= Calendar.getInstance(utcTZ);
utcCal.setTimeInMillis(utcAsLongValue);
Now you're calendar object is in UTC.
To display this though you're going to want to do something like the following:
import java.text.SimpleDateFormat;
import java.util.Date;
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
sdf.setTimeZone(utcTZ);
Date utcDate= utcCal.getTime();
sdf.formatDate(utcDate);
This will allow you to read in a timestamp for the UTC time zone stored as a long value and convert it to a Java Calendar or Date object.
Hope that gets you where you need to be.
Solution using, java.time the modern API
An Instant represents an instantaneous point on the timeline. It is independent of a timezone. In order to represent it in a timezone, you can use Instant#atZone or ZonedDateTime#ofInstant as shown below:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// A sample timestamp
long millis = 1620999618896L;
Instant instant = Instant.ofEpochMilli(millis);
System.out.println(instant);
ZonedDateTime zdtET = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtET);
// Alternatively
zdtET = ZonedDateTime.ofInstant(instant, ZoneId.of("America/New_York"));
System.out.println(zdtET);
}
}
Output:
2021-05-14T13:40:18.896Z
2021-05-14T09:40:18.896-04:00[America/New_York]
2021-05-14T09:40:18.896-04:00[America/New_York]
The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Note: For any reason, if you need to convert this object of Instant to an object of java.util.Date, you can do so as follows:
Date date = Date.from(instant);
Learn more about the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.