1

I stored a Date in sqlite db using INTEGER this:

System.currentTimeMillis()

And now i'm getting it back into a LONG and after to string with this:

myTextView.setText(convertDate(date_in_millis.toString(),"dd/MM/yyyy hh:mm:ss");

using this function

    public static String convertDate(String dateInMilliseconds, String dateFormat) {
    return DateFormat.format(dateFormat, Long.parseLong(dateInMilliseconds)).toString();
}

I'm in Italy.

Well, first of all i'm losing somewhere hours and minutes.

Second i'm not able to set 24h (with HH instead of hh)

I need to use API level 15 then i cannot use API 24 Libraries and i'm unable to use most answers i found.

WizardingStudios
  • 554
  • 2
  • 7
  • 22

2 Answers2

1

tl;dr

Instant.ofEpochMilli( 1_486_373_827_327L )
       .atZone( ZoneId.of( "Europe/Rome" ) )
       .format(
           DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" )
                            .withLocale( Locale.ITALY )
       )

06/02/2017 10:37:07

Avoid legacy date-time classes

The Question and other Answer are outdated. The troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.

Adding the library to your Android project is well worth the effort. The legacy date-time classes are a mess; avoiding them will save you much grief.

Using java.time

Convert your integer number that represents a number of milliseconds since the epoch reference date of 1970-01-01-T00:00:00Z to a Instant rather than a Date or Calendar. Call Instant.ofEpochMilli.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.ofEpochMilli( … );

Call toString to generate a String representing the date-time value.

instant.toString(): 2017-02-06T00:07:27.879Z

To see that same moment through the lens of a region’s wall-clock time, apply a time zone to get a ZonedDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "Europe/Rome" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString():

You can get the JVM’s current default time zone. If critical, you should ask the user to confirm. Beware that, like Locale, the current default can be changed at any moment, even during runtime, by any code in any thread of any app within the JVM.

ZoneId z = ZoneId.systemDefault();

To generate strings in other formats, you can let java.time automatically localize. To localize, specify:

  • FormatStyle to determine how long or abbreviated should the string be.
  • Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

You can ask for the JVM’s current default Locale. If critical, you should confirm with the user.

Locale locale = Locale.getDefault();

Note that locale has nothing to do with time zone, completely orthogonal issues, separate and distinct. Time zone determines the wall-clock time. Locale only applies to generating a string for presentation to the user. You could present a date-time in a Pacific/Auckland time zone with a Finnish locale, or present a date-time in the Europe/Rome with a Thai locale. The title of this Question used the word “Locale” but apparently meant “time zone”.

Example code. In this particular example with this particular formatting pattern, we do not technically need to specify a Locale. But better to make a habit of always specifying a Locale. If you forget to specify, you implicitly rely on the JVM’s current default Locale which can change at any moment during runtime.

Locale l = Locale.ITALY ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( l ) ;
String output = zdt.format( f );

Or you can specify a formatting pattern.

DateTimeFormatter fCustom = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" ).withLocale( l ) ;
String output2 = zdt.format( fCustom );

See example code run live at IdeOne.com.

millis: 1486373827327

instant.toString(): 2017-02-06T09:37:07.327Z

zdt.toString(): 2017-02-06T10:37:07.327+01:00[Europe/Rome]

output: 06/02/17 10.37

output2: 06/02/2017 10:37:07

No need to convert number to string

I see no need to convert your count-from-epoch long integer to a string. If you have a long or Long, just pass the long or the Long. Converting to, and then from, a String adds no value.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Dear Down-Voter: Please leave a criticism along with your vote. – Basil Bourque Feb 06 '17 at 02:48
  • 1
    Instead of using the standard libraries available in this JDK, suggesting some third party libraries that may or may not be supported tomorrow is questionable. While we all should be on JDK 8 that isn't always an option. While hardly perfect (and we have IBM to curse for that) pointing out JDK 8 and above libraries for an O/S that only supports JDK 7 and some extras is not helpful – stdunbar Feb 06 '17 at 02:54
  • @stdunbar Apparently you are uninformed as to the importance of the java.time classes, built on the history of one of the most-used Java libraries, [Joda-Time](http://www.joda.org/joda-time/). Characterizing the legacy date-time classes as “hardly perfect” is a laughable understatement. The legacy classes are a *disaster*, poorly designed, confusing, and flawed. As for “may or may not be supported tomorrow”, the java.time classes went through years of development and are now an official **permanent part of Java**. The back-port is built by members of the same team as java.time. – Basil Bourque Feb 06 '17 at 03:00
  • @BasilBourque thanks a lot for this great reply. Anyway i need to get Locale and TimeZone directly from the device, if possible. You answer should be perfect once this. Thanks again. – WizardingStudios Feb 12 '17 at 00:20
  • mmmmh... are you sure it is for Android? – WizardingStudios Feb 12 '17 at 00:37
  • @SteveRogers (A) Regarding Android, reread my Answer. In 2 places I mention using [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) for Android, adapting the ThreeTen-Backport project for Java 6 & 7 from the creators of java.time. And I link to a how-to posting, specific to Android. (B) Regarding getting default locale and time zone, I added code examples for both of those: `Locale.getDefault()` & `ZoneId.systemDefault()`. Beware that the current default can be changed at any moment by any code in any thread of any app within the JVM *during* runtime. Best to ask the user if critical. – Basil Bourque Feb 12 '17 at 01:44
  • @BasilBourque many thanks, i will take this post in a safe place. At this moment i'm not able to import external libraries but in future sure i will try :-) – WizardingStudios Feb 14 '17 at 13:52
0

Try using the Calendar class:

public static String convertDate(String dateInMilliseconds, String dateFormat) {
DateFormat df = new SimpleDateFormat(dateFormat);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(Long.parseLong(dateInMilliseconds));
c.add(Calendar.HOUR_OF_DAY, 1); //Work-around to get your lost hour
return df.format(c.getTime());
}

And you can use HH to get 24h