Displaying date/time in devices timezone on Android using Kotlin - android

So my app fetches from information from a JSON file from a server, of which there are a few date/time values. The time and date are in UTC. I need to display these in my app, in the users local timezone.
Example of the data from JSON:
"start":"2018-10-20 03:00:00","finish":"2018-10-20 05:00:00"
My code so far, which display the date and time fine, in UTC..
val dateStringStart = radioScheduleDMList.get(position).start
val dateStringEnd = radioScheduleDMList.get(position).finish
val date = SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()).parse(dateStringStart)
val dateEnd = SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()).parse(dateStringEnd)
val day = SimpleDateFormat("d MMM").format(date)
val startDate = SimpleDateFormat("ha").format(date)
val endDate = SimpleDateFormat("ha").format(dateEnd)
How can I go about displaying this data using the devices timezone? I've been googling for hours.
Using the above example, my app shows "20 OCT" for the date, and "3AM-5AM" for the time. In my case, I live in Australia (GMT+10) so I would expect day "20 OCT" and "1PM-3PM". In short, I want to detect the user’s timezone offset from UTC and apply it for display.

java.time and ThreeTenABP
DateTimeFormatter jsonFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d MMM", Locale.forLanguageTag("en-AU"));
DateTimeFormatter hourFormatter
= DateTimeFormatter.ofPattern("ha", Locale.forLanguageTag("en-AU"));
ZoneId zone = ZoneId.systemDefault();
String dateStringStart = "2018-10-20 03:00:00";
OffsetDateTime startDateTime = LocalDateTime.parse(dateStringStart, jsonFormatter)
.atOffset(ZoneOffset.UTC);
ZonedDateTime userStartDateTime = startDateTime.atZoneSameInstant(zone);
String startDayString = userStartDateTime.format(dateFormatter);
String startTimeString = userStartDateTime.format(hourFormatter);
System.out.println("Start day: " + startDayString);
System.out.println("Start hour: " + startTimeString);
I’m sorry I don’t write Kotlin. Can you translate from Java on your own? When I run the above code on a JVM with default time zone Australia/Brisbane it outputs:
Start day: 20 Oct
Start hour: 1PM
Just do similarly for the end date and time.
Question: Can I use java.time on Android?
Yes, java.time works nicely on 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 Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And 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).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Related

Display local date in textview (Kotlin)

I'm trying to display the local date (ie Tuesday, September 14, 2021) in a textview and I'm having a hard time finding a way to do it. Any tips or ideas?
You can use SimpleDateFormat class to format dates.
To acheive the format you specified in question, use this:
textView.text = SimpleDateFormat("EEEE, MMMM dd, yyyy").format(Date())
To understand the meaning of different date and time patterns, checkout this link.
java.time and a built-in localized format
Consider using java.time, the modern Java date and time API, for your date work. Please excuse my Java syntax. Declare a formatter:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.US);
Use like this:
LocalDate today = LocalDate.now(ZoneId.systemDefault());
String text = today.format(DATE_FORMATTER);
System.out.println(text);
When running today, output was:
Wednesday, September 15, 2021
Now assign this text into your TextView as described in the other answers.
Not only will you want to avoid the troublesome SimpleDateFormat class, you will also want to avoid writing your own format pattern string since this is error-prone. And your wish goes nicely hand in hand with the wish of your users to see the date printed in an appropriate format for their locale. In the above code I used Local.US for demonstration. In real code you will want to leave out that bit. Then the formatter will take on the default locale of the device, and users in all locales will be happy. Simply like this:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
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
Similar question: Date formatting based on user locale on android.
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.
Try this code
val sdf = SimpleDateFormat("EEE, MMMM dd, yyyy")
val current = sdf.format(Date())
textView.text = "$current"
Thank You everyone! Both of these solutions worked:
Solution 1:
val dateDisplay: TextView = findViewById(R.id.date)
dateDisplay.text = SimpleDateFormat("EEEE, MMMM dd, yyyy").format(Date())
Solution 2:
val sdf = SimpleDateFormat("EEE, MMMM dd, yyyy")
val current = sdf.format(Date())
val dateDisplay: TextView = findViewById(R.id.date)
dateDisplay.text = "$current"

how to convert 12hrs format time to utc in android

getting wrong results after converting 12hrs time format to utc.
String inputPa = "hh:mm a";
String OutPa = "yyyy-MM-dd'T'HH:mm:ss'Z'";
SimpleDateFormat inputPatter = new SimpleDateFormat(inputPa);
SimpleDateFormat outputPatter = new SimpleDateFormat(OutPa);
Date date1 = null;
String str1 = null;
try {
date1 = inputPatter.parse(txtStartTime.getText().toString());
str1 = outputPatter.format(date1);
Log.d("mycheck", str1);
} catch (ParseException e) {
e.printStackTrace();
}
java.time and ThreeTenABP
I assumed you wanted today’s date in your time zone.
String inputPa = "hh:mm a";
DateTimeFormatter timeFormatter12Hours = DateTimeFormatter.ofPattern(inputPa, Locale.ENGLISH);
ZoneId zone = ZoneId.of("America/Detroit");
String timeString = "11:34 AM";
LocalTime time = LocalTime.parse(timeString, timeFormatter12Hours);
Instant inst = LocalDate.now(zone).atTime(time).atZone(zone).toInstant();
System.out.println(inst);
Output from this example is:
2020-05-30T15:34:00Z
I would not bother converting the Instant to a string explicitly. It prints in UTC in your desired format when you print it, thus implicitly invoking its toString method (the format is ISO 8601, the international standard).
Please fill in your desired time zone. To rely on the device’ time zone setting set zone to ZoneId.systemDefault().
I am of course happy to use java.time, the modern Java date and time API. You can do that on your Android version too, see the details below.
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 use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And 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).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
public tring getCurrentUTC(Date time) {
SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
return outputFmt.format(time);
}
You can use this code to get current UTC time.
For you question, you just need convert the time string to the Date format.

Get the day like 1st Sunday, 2nd Tuesday

I want to get the day (e.g. 1st Sunday, 2nd Tuesday) of this month as Calendar.
How can I achieve this with class Calendar in Android? Thanks.
java.time and ThreeTenABP
Edit: The elegant solution uses a DateTimeFormatter:
Locale language = Locale.ENGLISH;
Map<Long, String> ordinalNumber = new HashMap<>(8);
ordinalNumber.put(1L, "1st");
ordinalNumber.put(2L, "2nd");
ordinalNumber.put(3L, "3rd");
ordinalNumber.put(4L, "4th");
ordinalNumber.put(5L, "5th");
DateTimeFormatter dayFormatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.ALIGNED_WEEK_OF_MONTH, ordinalNumber)
.appendPattern(" EEEE 'of the month'")
.toFormatter(language);
LocalDate date = LocalDate.now(ZoneId.of("Pacific/Auckland"));
String dayString = date.format(dayFormatter);
System.out.println("" + date + " is the " + dayString);
When I ran this snippet just now, it output:
2019-06-05 is the 1st Wednesday of the month
Obviously you can put in any date you wish other than today’s date in New Zealand.
The concept of aligned week of month defines the first week of the month as days 1 through 7, the 2nd week is 8 through 14, etc. So when a Wednesday is in week 1 according to this scheme, we also know that it must be the 1st Wednesday of the month. Same argument for other numbers.
I am not using the Calendar class you mentioned since it is poorly designed and long outdated. Instead I am using java.time, the modern Java date and time API.
Original code (a bit shorter, but nevertheless does a little more hand work):
String[] ordinalNumber = { "0th", "1st", "2nd", "3rd", "4th", "5th" };
LocalDate date = LocalDate.now(ZoneId.of("Pacific/Auckland"));
DayOfWeek day = date.getDayOfWeek();
int numberDowOfMonth = date.get(ChronoField.ALIGNED_WEEK_OF_MONTH);
String dayString = String.format(language, "%s %s of the month",
ordinalNumber[numberDowOfMonth],
day.getDisplayName(TextStyle.FULL_STANDALONE, language));
System.out.println("" + date + " is the " + dayString);
Output is the same as above.
There’s an unused 0th element of my ordinalNumber array. I only put it there because arrays are 0-based in Java and I wanted the other strings to be aligned with the numbers.
Question: Can I use java.time on Android?
Yes, java.time works nicely on 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 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 use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And 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).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Is Hour between an hour range?

The closest post I found on my question is How to compare current time with time range? But this doesn't work for me because i need to know if the current time on the users device is between a time range
so i got the current time like this...
DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss a");
String horaString = dateFormat.format(hour);
Log.i("ALO","HORAAAAAASSSSTRRRRIIIINNNNGGG---->"+horaString);
first = horaString.charAt(11);
Log.i("ALOP","Char at 11 ---->"+first);
char second=horaString.charAt(12);
Log.i("ALOP","Char at 12 ---->"+second);
char third=horaString.charAt(13);
char fourth=horaString.charAt(14);
char fith=horaString.charAt(15);
StringBuilder sb = new StringBuilder();
sb.append(first);
sb.append(second);
sb.append(third);
sb.append(fourth);
sb.append(fith);
String currentTime = sb.toString();
now what is need to do is
6:00>=currentTime<=8:30 //Can i still do the comparison with AM/PM?
So this is what I need to do if currentTime = 8:29 a method that lets me know is True with a boolean.
java.time and ThreeTenABP
final LocalTime rangeBegin = LocalTime.of(6, 0);
final LocalTime rangeEnd = LocalTime.of(8, 30);
LocalTime currentTime = LocalTime.now(ZoneId.of("America/Bogota"));
boolean inClosedRange = ! (currentTime.isBefore(rangeBegin) || currentTime.isAfter(rangeEnd));
If you prefer to trust the device time zone setting rather than a hard-coded (or configured) time zone, use LocalTime.now(ZoneId.systemDefault()).
Since LocalTime hasn’t got an isBeforeOrEqual method nor an isEqualOrAfter, I am putting the condition negatively: if the current time is neither strictly before nor strictly after the range, it must be within it. Some will prefer the longer but also more direct:
boolean inClosedRange = currentTime.equals(rangeBegin)
|| (currentTime.isAfter(rangeBegin) && currentTime.isBefore(rangeEnd))
|| currentTime.equals(rangeEnd);
You will notice how much simpler it still is than your code using SimpleDateFormat and Date. I personally also find it clearer. I am using and recommending java.time, the modern Java date and time API.
Question: Can I use java.time on Android?
Yes, java.time works nicely on 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 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 use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And 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).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
There are two useful command: After, Before.
Here is an example how you can use them:
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
Date fromTime = dateFormat.parse("6:00");
Date toTime = dateFormat.parse("8:30");
Date currentTime = dateFormat.parse(dateFormat.format(new Date()));
if(currentTime.after(fromTime) && currentTime.before(toTime)) {
// To do
}

android timestamp parsing gone wrong(always in 1970)

im trying to convert a string(with unix timestamp) to an date with the format ( dd-MM-yyyy)
and this is working partly. The problem im having now is that my date is in 17-01-1970 (instead of march 16 2015)
im converting it like this:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date d = null;
int dateMulti = Integer.parseInt(Date);
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(dateMulti);
String date = DateFormat.format("dd-MM-yyyy", cal).toString();
Log.d("test",date);
try {
d = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
where Date = 1427101853
and the result = 17-01-1970
what am i doing wrong?
You are using the wrong format string in the first line:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-mm-yyyy");
mm is minutes. Use MM (months) instead.
edit A Unix timestamp is a number of seconds since 01-01-1970 00:00:00 GMT. Java measures time in milliseconds since 01-01-1970 00:00:00 GMT. You need to multiply the Unix timestamp by 1000:
cal.setTimeInMillis(dateMulti * 1000L);
Why you have "dd-mm-yyyy" in SimpleDateFormat and "dd-MM-yyyy" in DateFormat.format? Use this :
String date = DateFormat.format("dd-mm-yyyy", cal).toString();
If you want minutes, if you want months you have to put MM like #Jesper said :)
I should like to contribute the modern answer.
java.time
DateTimeFormatter dateFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("da"));
String unixTimeStampString = "1427101853";
int dateMulti = Integer.parseInt(unixTimeStampString);
ZonedDateTime dateTime = Instant.ofEpochSecond(dateMulti)
.atZone(ZoneId.of("Africa/Conakry"));
String formattedDate = dateTime.format(dateFormatter);
System.out.println(formattedDate);
The output from this snippet is:
23-03-2015
The output agrees with an online converter (link at the bottom). It tells me your timestamp equals “03/23/2015 # 9:10am (UTC)” (it also agrees with the date you asked the question). Please substitute your time zone if it didn’t happen to be Africa/Conakry.
The date-time classes that you were using — SimpleDateFormat, Date and Calendar — are long outdated and poorly designed, so I suggest you skip them and use java.time, the modern Java date and time API, instead. A minor one among the many advantages is it accepts seconds since the epoch directly, so you don’t need to convert to milliseconds. While this was no big deal, doing your own time conversions is a bad habit, you get clearer, more convincing and less error-prone code from leaving the conversions to the appropriate library methods.
Question: Can I use java.time on Android?
Yes, java.time works nicely on 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, I’m told) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
I wrote and ran the above snippet using the backport to make sure it would be compatible with ThreeTenABP.
Links
Timestamp Converter
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).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
I was also facing the same issue when I was using SimpleDateFormat Here is a method I have made, which is working fine for me.
private String getmDate(long time1) {
java.util.Date time = new java.util.Date((long) time1 * 1000);
String date = DateFormat.format("dd-MMM-yyyy' at 'HH:mm a", time).toString();
return date + "";
}
you can change the date format as you desire.

Categories

Resources