-4

I create few small methods as an Util class, like the following code:

public class Util
{
  public static final String DATETIME_PATTERN="YYYY/MM/DD - HH:mm:ss";

  public static String getDateTime()
  {
    SimpleDateFormat sdf=new SimpleDateFormat(DATETIME_PATTERN);
    return sdf.format(getToday());
  }

  public static Date getToday()
  {
    //Calendar today=Calendar.getInstance(); //didn't help
    Calendar today=Calendar.getInstance(Locale.TAIWAN); //didn't fix
    //Calendar today=Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00")); //didn't fix as well
    return today.getTime();
  }
}

And, did a very simple run, like this:

//run in main class
System.out.println("Generating sitemap.xml, please wait..."+Util.getDateTime());

The result is a quite weird date -> 2017/07/187

//Console result:
Generating sitemap.xml, please wait...2017/07/187 - 15:27:21

Searched for similar question, and tried TimeZone, Locale, but didn't help. Any suggestions ?


BTW, here's my environment:

  • Windows7 x86
  • JDK 1.8.0.131 x86
  • eclipse oxygen x86
1615903
  • 32,635
  • 12
  • 70
  • 99
RRTW
  • 3,160
  • 1
  • 35
  • 54
  • Try using small case letters for the DD; so test: "YYYY/MM/dd - HH:mm:ss"; – Luftbaum Jul 06 '17 at 10:26
  • 2
    You should start by reading the documentation of the classes you are using: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html – 1615903 Jul 06 '17 at 10:36
  • When using Java 8 (and even if you didn’t), throw the outdated classes `Calendar` and `SimpleDateFormat` overboard and start using the modern and much nicer Java date and time API. – Ole V.V. Jul 06 '17 at 10:40
  • 1
    @Luftbaum, you’re on the right track, but you also need lowercase `yyyy`. – Ole V.V. Jul 06 '17 at 10:41
  • 1
    Always search Stack Overflow before posting. You would have found hundreds of examples of code to compare to yours to identify the fault. – Basil Bourque Jul 06 '17 at 16:37

2 Answers2

5

James Owen’s answer is correct: you need to use lowercase yyyy and lowercase dd in your format pattern string. That should do it.

What I want to contribute here is the modern and improved version of your utility class:

public class Util
{
    public static final String DATETIME_PATTERN = "yyyy/MM/dd - HH:mm:ss";

    public static String getDateTime()
    {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DATETIME_PATTERN);
        return getNow().format(dtf);
    }

    public static ZonedDateTime getNow()
    {
        return ZonedDateTime.now(ZoneId.of("Asia/Taipei"));
    }
}

Since you are using Java 8, there is no reason for you to take the trouble with the long outdated classes SimpleDateFormat, Date and Calendar. The modern classes are generally much nicer to work with. I took the freedom of also returning a bit more information from getToday() (and renamed it to getNow): it now tells you both the current time and the time zone, which makes sure that getDateTime() also formats the time in this time zone.

I preferred Asia/Taipei as time zone. It gives the same result as GMT+08:00, but (1) is futureproof in case Taiwan again introduces summer time (DST) (2) is clearer to read and tells the reader more about why this particular offset was chosen (Taiwan has had summer time before, last time was in 1979).

An example of the trouble with SimpleDateFormat

One out of many objections to the old classes is they tend to pretend everything is well when it isn’t. You got an incorrect output and no explanation why. You would have preferred some error message. The modern classes behave a bit better on this point. Say you had used your pattern string with my code. It gives

java.time.DateTimeException: Field DayOfYear cannot be printed as the value 187 exceeds the maximum print width of 2

Day of year? You may have to check the documentation to see that capital D is for day-of-year while small d is for day-of-month. Let’s fix:

public static final String DATETIME_PATTERN = "YYYY/MM/dd - HH:mm:ss";

Unfortunately DateTimeFormatter does not catch your other error, the uppercase YYYY. This means week-based year and is only useful with a week number. But theoretically you might have intended this, the class has no chance to tell. If you had tried to parse with the same format, you would have been told you couldn’t.

If you need a Date

Maybe you need a Date object for some legacy API that you cannot change. In Java 8 the old classes have been fitted with conversion methods, so it’s easy (when you know how). You may for example add this method:

public static Date getNowAsOldfashionedDateObject() {
    return Date.from(getNow().toInstant());
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
3

It's a problem with the way you are formatting the date. Try changing it to this

  public static final String DATETIME_PATTERN="yyyy/MM/dd - HH:mm:ss";
James Owen
  • 256
  • 1
  • 11