I am in the process of migrating my code to use the java.time package but I found that DateTimeFormatter does not interpret the time zone "BST" (British Summer Time) correctly.
Instead of making it UTC+0100, it converted it to Pacific/Bougainville timezone.
Does anybody know how I can fix this without going back to the old SimpleDateFormat, or use an explicit timezone? My code needs to run in multiple regions in the world.
This timestamp format is obtained by querying another system so I won't be able to change it. It seems SimpleDateFormat can recognize the timezone properly. My test code is below:
String sTime = "Fri Jun 07 14:07:07 BST 2019";
DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE MMM dd kk:mm:ss z yyyy");
ZonedDateTime zd = ZonedDateTime.parse(sTime, FORMATTER);
System.out.println("The time zone: " + zd.getZone());
FileTime ftReturn = FileTime.from(zd.toEpochSecond(), TimeUnit.SECONDS);
System.out.println("File time is: " + ftReturn);
DateFormat df = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);
Date dtDD = df.parse(sTime);
Calendar calendar = Calendar.getInstance();
calendar.setTime(dtDD);
FileTime ftReturn1 = FileTime.fromMillis(calendar.getTimeInMillis());
System.out.println("File time1 is: " + ftReturn1);
Test result:
The time zone: Pacific/Bougainville
File time is: 2019-06-07T03:07:07Z
File time1 is: 2019-06-07T13:07:07Z
According to https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#SHORT_IDS:
BST - Asia/Dhaka
So I guess you should not use that abbreviation.
EDIT: Just found this question, which answers it.
So don't use Bangladesh Standard Time ;) Instead use ZoneId.of("Europe/London")
First, you’re trying to solve a task that cannot be solved. Three letter time zone abbreviations are ambiguous, I think more often than not. So if you solve the issue for Europe/London, you will have it again when you meet EST, IST, CST, CDT, PST, WST, and so on and so forth. Or when you meet a string where BST was intended to mean Brazil Summer Time, Bangladesh Standard Time or Bougainville Standard Time. Still more interpretations exist. Instead get an unambiguous string like one with a UTC offset rather than a time zone abbreviation, best a string in ISO 8601 format like 2019-06-07T14:07:07+01:00.
But if you’re sure that BST will always mean British Summer Time in your world, the short-sighted solution may be to tell the DateTimeFormatter which time zone/s you prefer:
String sTime = "Fri Jun 07 14:07:07 BST 2019";
ZoneId preferredZone = ZoneId.of("Europe/London");
DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("EEE MMM dd HH:mm:ss ")
.appendZoneText(TextStyle.SHORT, Collections.singleton(preferredZone))
.appendPattern(" yyyy")
.toFormatter(Locale.ROOT);
ZonedDateTime zd = ZonedDateTime.parse(sTime, FORMATTER);
System.out.println("The time zone: " + zd.getZone());
FileTime ftReturn = FileTime.from(zd.toEpochSecond(), TimeUnit.SECONDS);
System.out.println("File time is: " + ftReturn);
Output is:
The time zone: Europe/London
File time is: 2019-06-07T13:07:07Z
Links
Time Zone Abbreviations – Worldwide List
Documentation of the two-arg DateTimeFormatterBuilder.appendZoneText
Wikipedia article: ISO 8601
BST is ambiguous, as are many such abbreviations for timezones.
This solution is not great, but if you absolutely have to give precedence to BST to mean British Summer Time then you could just check whether the string contains that zone, and if it does, remove the zone and apply it manually.
String s = "Fri Jun 07 14:07:07 BST 2019";
if (s.contains(" BST ")) { // Check could be improved
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd kk:mm:ss yyyy");
s = s.replace(" BST ", " ");
ZonedDateTime dateTime = LocalDateTime.parse(s, formatter).atZone(ZoneOffset.ofHours(1));
}
else {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd kk:mm:ss z yyyy");
// Normal parsing
}
In future, consider representing your dates (either on-disk, or across an API) as offset strings instead, for example +01:00
Related
I have a DateTime in the format of Tue, 30 Apr 2019 16:00:00 +0800 which is RFC 2822 formatted date
I need to convert this to the given timezone in the DateTime which is +0800
So if i summarized,
DateGiven = Tue, 30 Apr 2019 16:00:00 +0800
DateWanted = 01-05-2019 00:00:00
How can i achieve this in Java?
I have tried the below code but it gives 08 hours lesser than the current time which is
30-04-2019 08:00:00
Code i tried
String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date startDate = format.parse(programmeDetails.get("startdate").toString());
//Local time zone
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
//Time in GMT
Date dttt= dateFormatLocal.parse( dateFormatGmt.format(startDate) );
You are on right approach but just use java-8 date time API module, first create DateTimeFormatter with the input format representation
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z");
And then use OffsetDateTime to parse string with offset
OffsetDateTime dateTime = OffsetDateTime.parse("Tue, 30 Apr 2019 16:00:00 +0800",formatter);
And the call the toLocalDateTime() method to get the local time
LocalDateTime localDateTime = dateTime.toLocalDateTime(); //2019-04-30T16:00
If you want the output in particular format again you can use DateTimeFormatter
localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) //2019-04-30T16:00:00
Note : As #Ole V.V pointed in comment, after parsing the input string into util.Date you are getting the UTC time
The class Date represents a specific instant in time, with millisecond precision.
So now if you convert the parsed date time into UTC you get 2019-04-30T08:00Z without offset, so you can use withOffsetSameInstant to convert it into any particular timezone
dateTime.withOffsetSameInstant(ZoneOffset.UTC)
You misunderstood. According to RFC 2822 +0800 means that an offset of 8 hours 0 minutes has already been applied to the time compared to UTC. So the output you got was the correct GMT time.
java.time
I recommend you skip the old and outdated classes SimpleDateFOrmat and Date. It’s much nicer to work with java.time, the modern Java date and time API. Furthermore it has the RFC format built in, so we don’t need to write our own formatter.
OffsetDateTime parsedDateTime = OffsetDateTime
.parse("Tue, 30 Apr 2019 16:00:00 +0800",
DateTimeFormatter.RFC_1123_DATE_TIME);
ZonedDateTime dateTimeInSingapore
= parsedDateTime.atZoneSameInstant(ZoneId.of("Asia/Singapore"));
System.out.println("In Singapore: " + dateTimeInSingapore);
OffsetDateTime dateTimeInGmt
= parsedDateTime.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println("In GMT: " + dateTimeInGmt);
Output:
In Singapore: 2019-04-30T16:00+08:00[Asia/Singapore]
In GMT: 2019-04-30T08:00Z
The built-in formatter is named RFC_1123_DATE_TIME because the same format is used in multiple Requests for Comments (RFCs).
Links
RFC 2822 Internet Message Format
Oracle tutorial: Date Time explaining how to use java.time.
with the help of #ole v.v's explanation i have separated the datetime value for two
1. time
2. timezone
then i used this coding to extract the datetime which is related to the given timezone
//convert datetime to give timezone
private static String DateTimeConverter (String timeVal, String timeZone)
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat offsetDateFormat2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
offsetDateFormat2.setTimeZone(TimeZone.getTimeZone(timeZone));
String result =null;
try {
result = offsetDateFormat2.format(format.parse(timeVal));
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
I am unable to parse this date. Anyone notice any mistakes? They all seem to fail.
I have tried multiple patterns with multiple Locale types.
Here is my strategy:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Locale;
public class Test {
static void check(Locale locale){
String dateString = "Aug 15, 2017, 4:58 PM ET";
DateFormat format1 = new SimpleDateFormat("MMM dd, yyyy, h:mm aa zz", locale);
DateFormat format2 = new SimpleDateFormat("MMM dd, yyyy, h:mm a z", locale);
DateFormat format3 = new SimpleDateFormat("MMM dd, yyyy, hh:mm a z", locale);
DateFormat format4 = new SimpleDateFormat("MMM dd, yyyy, K:mm a z", locale);
DateFormat format5 = new SimpleDateFormat("MMM dd, yyyy, KK:mm a z", locale);
for (DateFormat format : Arrays.asList(format1, format2, format3, format4, format5)) {
try {
System.out.println(format.parse(dateString));
} catch (ParseException ex){
System.out.println("Failed");
}
}
}
public static void main(String[] args) {
Arrays.asList(Locale.ENGLISH, Locale.UK, Locale.US, Locale.CANADA, Locale.ROOT, Locale.getDefault()).forEach(Test::check);
}
}
As many have already said, ET is not a timezone. It's an abbreviation commonly used to refer to both EST and EDT (Eastern Standard Time and Eastern Daylight Time), but there are more than one timezone that uses it.
Short names (like EST and EDT) aren't timezones as well, because such abbreviations are ambiguous and not standard. There are more than one timezone that can use the same abbreviations.
The ideal is to use IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin).
But the use of short names like EST and ET is widespread and common, so we must live with it (and do some workarounds as well).
The first thing is to define which timezone you want to use as ET (and this will be a very arbitrary choice, but there's no other way since ET is ambiguous). In the example below, I've chosen America/New_York. You can see the list of all available timezones (and choose one that fits best to your needs) using the java.util.TimeZone class (calling TimeZone.getAvailableIDs()).
It's possible to overwrite the short names used by SimpleDateFormat, using the java.text.DateFormatSymbols class. So, one solution is to get the current symbols and overwrite just the timezone we want:
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy, h:mm a z", Locale.ENGLISH);
// get current date symbols
String[][] zoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
for (int i = 0; i < zoneStrings.length; i++) {
// overwrite just America/New_York (my arbitrary choice to be "ET")
if (zoneStrings[i][0].equals("America/New_York")) {
zoneStrings[i][2] = "ET"; // short name for standard time
zoneStrings[i][4] = "ET"; // short name for daylight time
break;
}
}
// create another date symbols and set in the formatter
DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
symbols.setZoneStrings(zoneStrings);
sdf.setDateFormatSymbols(symbols);
String dateString = "Aug 15, 2017, 4:58 PM ET";
System.out.println(sdf.parse(dateString));
This will parse ET as America/New_York, and all other existing built-in zones won't be affected.
Check the javadoc for more details about DateFormatSymbols.
Also note that I used Locale.ENGLISH, because the month name (Aug) is in English. If I don't specify the locale, the system's default will be used, and it's not guaranteed to always be English. Even it the default is correct, it can be changed without notice, even at runtime, so it's better to use an explicit locale.
Java new Date/Time API
If you're using Java 8, you can replace this code with the new java.time API. It's easier, less bugged and less error-prone than the old SimpleDateFormat and Calendar APIs.
All relevant classes are in java.time package. You just need to define a java.util.Set of prefered zones and set it to a java.time.format.DateTimeFormatter. Then you parse it to a java.time.ZonedDateTime - if you still need to work with a java.util.Date, you can easily convert it:
// prefered zones
Set<ZoneId> preferredZones = new HashSet<>();
preferredZones.add(ZoneId.of("America/New_York"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date and time
.appendPattern("MMM dd, yyyy, h:mm a ")
// zone (use set of prefered zones)
.appendZoneText(TextStyle.SHORT, preferredZones)
// create formatter (use English locale for month name)
.toFormatter(Locale.ENGLISH);
String dateString = "Aug 15, 2017, 4:58 PM ET";
// parse string
ZonedDateTime zdt = ZonedDateTime.parse(dateString, fmt);
// convert to java.util.Date
Date date = Date.from(zdt.toInstant());
Daylight Saving Time issues
There are some corner cases. America/New_York timezone has Daylight Saving Time (DST), so when it starts and ends, you can have unexpected results.
If I get the date when DST ends:
String dateString = "Nov 02, 2008, 1:30 AM ET";
At 2 AM, clocks shift 1 hour back to 1 AM, so the local times between 1 AM and 1:59 AM exist twice (in DST and in non-DST offsets).
SimpleDateFormat will get the offset after DST ends (-05:00) so the date will be equivalent to 2008-11-02T01:30-05:00, while ZonedDateTime will get the offset before (-04:00) and the date will be equivalent to 2008-11-02T01:30-04:00.
Fortunately, ZonedDateTime has the withLaterOffsetAtOverlap() method, that returns the corresponding date at the offset after DST ends. So you can emulate SimpleDateFormat's behaviour calling this method.
If I get the date when DST starts, though:
String dateString = "Mar 09, 2008, 2:30 AM ET";
At 2 AM, clocks shift forward to 3 AM, so local times between 2 AM and 2:59 AM don't exist. In this case, both SimpleDateFormat and ZonedDateTime will adjust the time to 3:30 AM and use the DST offset (-04:00) - the date will be equivalent to 2008-03-09T03:30-04:00.
Your format is fine, it is just your date that is wrong. ET is not a valid zone identifier.
With TimeZone.getAvailableIDs() you can look at valid zone IDs.
I would like to convert my string date to int but I get an error, example of my date 'dim. janv. 23 24:00:00 +0000 2011`
This is part of my code :
String created_at = (String) jsonObject.get("created_at");
System.out.println("la date de création de tweet est: " + created_at);
DateFormat df = new SimpleDateFormat(" ddd. MMMM. EE HH:mm:ss z yyyy");
String s= df.format(created_at);
int out=Integer.valueOf(s);
System.out.println("new date " +out);
And the output is:
java.lang.IllegalArgumentException: Cannot format given Object as a Date.
Well, you already have the date in String format and that's what the format method does. I am assuming what you want to do here is to parse the date (into Date object) and not format.
Also, it looks like the date is in French locale, so you need to use appropriate locale along with SimpleDateFormat and use parse method, e.g.:
DateFormat df = new SimpleDateFormat("EEE MMMM dd HH:mm:ss z yyyy", Locale.FRANCE);
Date date = df.parse("dim. janv. 23 24:00:00 +0000 2011");
System.out.println(date);
This would give you the Date object. If you want to format it differently, you can call format method with different format.
Update
Also, it looks like you are calling overloaded version of format method (by passing in a String and not a Date object. This evantually calls format method of TextFormat class (javadoc here) and that's why you get that Exception.
I am aware that there is an accepted answer already. I am posting this to inspire you and anyone else to drop the outdated classes DateFormat and SimpleDateFormat. These days we have so much better in the modern DateTimeFormatter and friends, these classes tend to be much more programmer friendly. So use these if you can — which you can.
System.out.println("la date de création de tweet est: " + created_at);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss xx uuuu",
Locale.FRENCH);
OffsetDateTime dateTime = OffsetDateTime.parse(created_at, dtf);
This prints:
la date de création de tweet est: dim. janv. 23 24:00:00 +0000 2011
2011-01-24T00:00Z
In French the dots are part of the abbreviations for day of week and month, so they should not be explicit in the format pattern string. Also be aware that you don’t have a leading space in there (unless your date-time string has one too). The result is correct since midnight at 24 hours on 23th of January is the same as 0 hours in the 24th.
The other string from the comment, "Tue Feb 08 12:30:27 +0000 2011", is in the same format, only in English. So you need not change the format pattern, only the locale:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss xx uuuu",
Locale.ENGLISH);
Now the result is:
la date de création de tweet est: Tue Feb 08 12:30:27 +0000 2011
2011-02-08T12:30:27Z
I didn’t understand the part about converting to integer. I noticed you tried Integer.valueOf(s) in the code in the question, which will only work if you format the date-time into a string of digits first. For example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMdd");
String s = dateTime.format(formatter);
int out = Integer.parseInt(s);
System.out.println("new date " + out);
This prints
new date 20110124
But I probably guessed incorrectly at what you are aiming at. I shall be happy to edit if you explain your requirement better. I used parseInt() en lieu of valueOf(), the result is the same, I just avoid the automatic conversion from Integer to int.
Edit: What if the date of creation of tweet is for example "dim. janv. 23 24:00:10 +0000 2011"? That is, 10 seconds past midnight. Then we get Invalid value for HourOfDay (valid values 0 - 23): 24.
While Java apparently accepts 24:00:00 as a time, it thinks that times after midnight should written as for example 0:00:10 on the following day. However, we can easily relax that requirement:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss xx uuuu",
Locale.FRENCH)
.withResolverStyle(ResolverStyle.LENIENT);
Date time formatters come with three resolver styles, strict, smart (the default) and lenient. Using the last one we get
2011-01-24T00:00:10Z
Again, as expected, 24:00:10 on 23th of January equals 0:00:10 on the 24th.
I have the following code
protected void amethod1() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" .
I am testing this code in Chicago and the local timezone is CDT.
I am not able to understand why the time value changes from 16:24:59 to 11:24:59 even though. Am I missing something in the defined format of the date?
Class Date doesn't contain any timezone at all. It's just a number of milliseconds since 01.01.1970 00:00:00 GMT. If you try to see, what formattedDate contains with System.out.println or debugger, you'll get formatted date for your local timezone. 11:24:59 CDT and 16:24:59 UTC are the same time, so result is correct.
Is java.util.Date using TimeZone?
It is better to use jodatime or Java 8 Time API in order to better manage time and timezones.
First, you are getting the correct time. When Daylight Savings Time is in use in Chicago (which it is on May 18), the time is 11:24:59 when it’s 16:24:59 in UTC. So your Date value represents the same point in time. This is all you can expect from a Date.
I understand that you want not just a point in time, but also the UTC time zone. Since Axel P has already recommended Java 8 date and time API, I just wanted to fill in the details:
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern(dateFormatStr, Locale.US);
ZonedDateTime dateTime = ZonedDateTime.parse(strDate, parseFormatter);
The result is
2017-05-18T16:24:59Z[UTC]
If you always want the UTC time zone, the Instant class is just right for it, so you will probably want to convert to it:
Instant instant = dateTime.toInstant();
Instants are always in UTC, popularly speaking.
SimpleDateFormat myFmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now=new Date();
System.out.println(myFmt.format(now));
I hope I can help you. If you can,please adopt.Thank you
The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" . Why? because your time zone running -5 hour from UTC time you will find in below link wiki time zone abbreviations, if you want result in same timezone you need to specify timezone in formater Hope you get my concern
https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
public static void amethod1() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("formattedDate: "+dateFormat.format(formattedDate));
}
You specified timezone, that's why after parsing time on current timezone (where you are), SimpleDateFormat sets UTC timezone. When you try to output your date, it is displayed on your current timezone
It appears you would need to specify the TimeZone as well when you format the Date For eg. .TimeZone.setDefault(TimeZone.getTimeZone("PST"));
Have a look at this discussion TimeZone
The output of a Date depends on the format specified, where you can specify the timezone, as shown in the example below:
protected void amethod2() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("Date: " + formattedDate);
// Thu May 18 17:24:59 BST 2017, BST is my system default timezone
// Set the time zone to UTC for the calendar of dateFormat
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Date in timezone UTC: " + dateFormat.format(formattedDate));
// Thu May 18 16:24:59 UTC 2017
// Set the time zone to America/Chicago
dateFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println("Date in timezone America/Chicago: " + dateFormat.format(formattedDate));
// Thu May 18 11:24:59 CDT 2017
}
As for the IDs, such as "UTC" and "America/Chicago" in the example, you can get a complete list of them via TimeZone.getAvailableIDs(). You can print them out to have a look:
Arrays.stream(java.util.TimeZone.getAvailableIDs()).forEach(System.out::println);
And you'll have:
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
...
I want this date to be displayed in GMT "01/01/2100"
Expecting result - "Fri Jan 01 00:00:00 GMT 2100"
Result i am seeing - "Thu Dec 31 19:00:00 EST 2099"
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
try{
Date myDate = sdf.parse("01/01/2100");
System.out.println(myDate);
}
catch(Exception e){
}
I want the result myDate in GMT time not EST
Example 2
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("gmt"));
try{
Date myDate = sdf.parse("2010-05-23 09:01:02");
SimpleDateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm");
System.out.println("MYDATE: " +df.format(myDate));
}
catch(Exception e){
}
Output: Sun, 23 May 2010, 05:01
Expecting: Sun, 23 May 2010, 09:01
http://goo.gl/uIy9RQ - URL for my project code, run and check the result
As already stated in the comments you have to apply the date format to the Date. I modified your code to display the myDate
try{
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Date myDate = sdf.parse("01/01/2100");
System.out.println(sdf.format(myDate));
sdf.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println(sdf.format(myDate));
}
catch(Exception e){
// error handling
}
Output is
01/01/2100
31/12/2099
But do not forget the date still contains information about hours, minutes, seconds etc. In respect to the applied date formatter this information is not shown when running
System.out.println(sdf.format(myDate));
If you need to set some fields of the date, you should make use of the Calendar.
For customizing date format use below
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm");
String date = df.format(Calendar.getInstance().getTime());
Date format parameter can be any one of the following
"yyMMddHHmmssZ"-------------------- 010704120856-0700
"K:mm a, z" ----------------------- 0:08 PM, PDT
"yyyy.MM.dd G 'at' HH:mm:ss z" ---- 2001.07.04 AD at 12:08:56 PDT
"EEE, d MMM yyyy HH:mm:ss Z"------- Wed, 4 Jul 2001 12:08:56 -0700
"h:mm a" -------------------------- 12:08 PM
"EEE, MMM d, ''yy" ---------------- Wed, Jul 4, '01
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"------- 2001-07-04T12:08:56.235-0700
"hh 'o''clock' a, zzzz" ----------- 12 o'clock PM, Pacific Daylight Time
toString on java.util.Date Is Misleading
As has been stated many times before on Stack Overflow, the toString method of java.util.Date silently applies the JVM’s current default time zone when generating the textual representation of the date-time value. An unfortunate design choice.
The old java.util.Date/.Calendar classes are notoriously troublesome. Avoid them. In Java 8 and later, use the built-in java.time framework. Defined by JSR 310, extended by the ThreeTen-Extra project. See Tutorial.
UTC
Basically UTC is the same as GMT in this context.
java.time
The java.time framework includes the class LocalDate for a date-only value without time-of-day nor time zone.
Note that getting the current date requires a time zone even though no time zone is stored internally. For any given moment the date varies around the world by time zone, with a new day dawning earlier in the east.
Use a proper time zone name. Never use 3-4 letter codes such as EST as they are neither standardized nor unique.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
The LocalDate::toString method generates a string in standard ISO 8601 format: 2016-01-23.
Joda-Time
If Java 8 technology is not available to you, add the very successful Joda-Time library. Joda-Time inspired the java.time.
In this case the code is similar that seen above.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
LocalDate localDate = new LocalDate( zone );