How to get the current date and timezone in numeric format

I want to print the current date in this format 2017/06/05

> Year/Month/Day

and next to it the current timezone in this format+3

I used this code

String DateToday  = DateFormat.getDateInstance().format(new Date());
String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName();
txt.setText(DateToday + " | "+ TZtoday );

      

But it looks like this:

June 5, 2017 | Arabia Standard Time

I want like this:

2017/06/05 | +3

+3


source to share


4 answers


SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd | X");
System.out.println(sdf.format(new Date()));

      

approaching, but the timezone is printed with a leading zero:

2017/06/05 | +03

      

I suppose you could remove the leading zeros from the timezone if you need:



SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat zone = new SimpleDateFormat("ZZZZZ"); // = +03:00
String tz = zone.format(new Date()).split(":")[0]
    .replaceAll("^(\\+|-)0", "$1"); // = +3
System.out.println(sdf.format(new Date()) + " | " + tz);

      

which gives:

2017/06/05 | +3

      

+2


source


I know that you're on Android, and I know that offers built-in Android - it has long been obsolete classes, such as DateFormat

, SimpleDateFormat

, Date

and Calendar

. However, I am saying that if you are doing something with dates and / or times and / or time zones, you should seriously consider skipping these classes and moving on to their modern replacements. This will require you to have ThreeTenABP . Then I suggest the following:

    ZonedDateTime date = ZonedDateTime.now(ZoneId.systemDefault());
    String tzToday = date.format(DateTimeFormatter.ofPattern("uuuu/MM/dd | x"));
    tzToday = tzToday.replaceFirst("(?<=\\+|-)0", "");

      

Result on my computer:

2017/06/05 | +2

      

The result in Asia / Kathmandu timezone may not be what you wanted:



2017/06/05 | +545

      

You might think my code snippet is not very beneficial due to the use of old classes. You can take my word for it when I say that there are so many cases where old classes give you nasty surprises, so the sooner you can start using the new ones, the better. For example, you might make a typo in your formatting template string and notice how you get amazing results with the old classes without any indication that something is wrong, while the new ones will try to collect a meaningful error message.

Another detail I want to point out is that the system and JVM timezones are read only once (changing the timezone back to now()

to make sure it is used for the time). Your code in the question first formats the date, then reads the timezone. If someone changes the timezone in between, the result will be inconsistent. Very unlikely, but it also means that hardly anyone will be able to figure out what happened.

(?<=\\+|-)

in the regex is the lookbehind: I replace the 0

preceding one +

with either -

an empty string. I searched in vain for a way to format the zone offset as +3

you wish, so I resorted to the method replaceFirst

.

Additional reference: How to use ThreeTenABP in Android project .

+3


source


Just complementing @ Ole VV's answer , I found another way to do it using ThreeTenABP , but without replacing the regex (although I don't think it is much easier, more on that below).

Using DateTimeFormatterBuilder

, you can use HashMap

which maps the offset values ​​to String

. That way, for whole hours of offset (for example +03:00

), you can map the corresponding value to a string +3

, etc.

The only problem is that it ZoneOffset

has seconds precision . Both the minimum and maximum values ​​are equal to UTC-18:00:00

and respectively UTC+18:00:00

. Thus, all the possible values of UTC-18:00:00

, UTC-17:59:59

, UTC-17:59:58

and so on. And the formatting requires all possible values ​​to be displayed (otherwise it will display the offset seconds value), so the map will have over 120k entries!

To build this map, I did 2 loops:

  • The first cycle displays all hour offsets ( +01:00

    before +1

    , -02:00

    before -2

    , etc.)
  • The second loop displays all other values ​​(they remain unchanged):
    • whole hours> = 10 (for example +10:00

      )
    • not whole hours (for example +05:30

      )

Code to create formatting:

// builds a hashmap to map all offset values
Map<Long, String> map = new HashMap<>();

// First loop: Map whole hours from 1 to 9 and from -9 to -1
// So a "+01:00" offset is displayed as "+1"
for (int i = 1; i <= 9; i++) {
    long seconds = ZoneOffset.ofHours(i).getTotalSeconds();
    // 1 hour offset maps to "+1" and so on
    map.put(seconds, "+" + i);
    // -1 hour offset maps to "-1" and so on
    map.put(-seconds, "-" + i);
}

// second loop: Need to map all other possible values for not-whole hours
// offsets like "+10:00" and "+01:30" are not changed
int minOffset = ZoneOffset.MIN.getTotalSeconds();
int maxOffset = ZoneOffset.MAX.getTotalSeconds();
for (long i = minOffset; i <= maxOffset; i++) {
    // the map already contains whole hours, don't need to overwrite the values
    if (!map.containsKey(i)) {
        // uses default String representation (like "+05:30")
        map.put(i, ZoneOffset.ofTotalSeconds((int) i).getId());
    }
}

// create the formatter
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                // year/month/day and the "|"
                .appendPattern("uuuu/MM/dd | ")
                // use the map of custom values (offset will use the values in the map)
                .appendText(ChronoField.OFFSET_SECONDS, map)
                // create formatter
                .toFormatter();

      

Some tests:

LocalDateTime dt = LocalDateTime.of(2017, 5, 1, 10, 0);
ZonedDateTime z = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); // UTC-03:00
System.out.println(formatter.format(z)); // 2017/05/01 | -3

// just picking some timezone in Arabia Stardard Time
// (there are more than one timezone in AST: https://en.wikipedia.org/wiki/UTC%2B03:00#Arabia_Standard_Time)
// I don't know in which one you are
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Qatar")); // UTC+03:00
System.out.println(formatter.format(z)); // 2017/05/01 | +3

// 2-digit offset
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Vladivostok")); // UTC+10:00
System.out.println(formatter.format(z)); // 2017/05/01 | +10:00

// not whole hour
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Kathmandu")); // UTC+05:45
System.out.println(formatter.format(z)); // 2017/05/01 | +05:45

      

Output:

2017/05/01 | -3
2017/05/01 | +3
2017/05/01 | +10: 00
2017/05/01 | +05: 45


Notes:

  • I don't know if it's better to have a map with 120K maps than using regular expressions (that's up to you). This approach creates a large map, but at least does not require post-processing of the output afterwards (not sure if this is a reasonable compromise)
  • If you want shifts for an entire hour> = 10 to display as +10

    , +11

    etc., just change the first loop for

    to for (int i = 1; i <= maxOffsetYouWant; i++)

    - just reminding you that the maximum possible value for maxOffsetYouWant

    is 18
    .
+1


source


Use the following logic to get the date format you want.

    public static void main(String[] args) {

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, 1);
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(cal.getTime());
// Output "Wed Sep 26 14:23:28 EST 2012"

        String formatted = format1.format(cal.getTime());
        String formattedmain=formatted.replace("-","/");
        System.out.println(formatted);
        // Output "2012-09-26"
        System.out.println(formattedmain);

//Output :- 2017/06/06


    }

      

0


source







All Articles