I'm currently running to the following problem:
I'm running this command
TimeZone.getDefault();
While my phone (Galaxy S6 with Android 7.0) is configured to with system language of Arabic (العربية to be precise).
The output of this call is: GMT+٠٢:٠٠ and not GMT+02:00 as I would expect it to be.
I've noticed that this issue happens only on Samsung devices (at least from the errors that I saw in my logs).
Is there a way to make sure that the timezone which I'm getting will be in the format of GMT+02:00 regardless of the locale of the phone?
The solution which I've found:
final static String am = "GMT-%02d:%02d";
final static String pm = "GMT+%02d:%02d";
final String timezone = String.format(Locale.ENGLISH, offset < 0 ? am : pm, hours, minutes);
Related
How one could get Chinese New Year Date on Android?
Since API level 24 Android has Chinese Calendar class.
https://developer.android.com/reference/android/icu/util/ChineseCalendar
However, doing it like this returns wrong date (Feb 12 for 2023).
val chinese = ChineseCalendar.getInstance()
chinese.set(ChineseCalendar.MONTH, 0)
chinese.set(ChineseCalendar.DAY_OF_MONTH, 1)
I was able to get Gregorian date for Chinese new year in the following way. Getting Chinese calendar is done using simple instantiation ChineseCalendar(). No need to call getInstance().
val chinese = ChineseCalendar()
chinese.set(ChineseCalendar.MONTH, 0)
chinese.set(ChineseCalendar.DAY_OF_MONTH, 1)
println("chinese " + chinese.time.toString())
In the logs I got
chinese Sun Jan 22 13:24:41 GMT+02:00 2023
You can also add year to get next new year date, like this
chinese.add(ChineseCalendar.YEAR, 1)
and get
chinese Sat Feb 10 13:27:41 GMT+02:00 2024
I was working on Time conversion from One Locale to another (US to Swedish) in android using Java. It is working well on all the devices except Samsung devices.
DateTimeFormatter parser = DateTimeFormatter.ofPattern("hh:mm a", Locale.US);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", new Locale("sv","SE"));
LocalTime time = LocalTime.parse("06:45 AM", parser);
String formatted = time.format(formatter);
In other devices I am getting output as 06:45 FM
In samsung devices I am getting it as
06:45 AM itself.
I want the the output to show as 06:45 FM in every device type.
Note : This issue only occurs for Time conversion,Date conversion (month names) works fine.
Thanks in advance.
Context
This is an Android App running on API 29 (with a Min of 23).
I'm using ThirteenTenABP
Issue
I'm simply debugging some code and I do the following:
val zonedDateTime = ZonedDateTime.of(
LocalDateTime.of(1900, 1, 1, 15, 15, 0),
ZoneId.of("Europe/Amsterdam"))
This prints (toString() as:
1900-01-01T15:15+00:19:32[Europe/Amsterdam]
Expected
I would have expected to see 1900-01-01T15:15+02:00:00[Europe/Amsterdam] or similar.
The current Offset from UTC in Amsterdam is +2 due to daylight savings. Yet, I see these 19 minutes and 32 seconds.
This means that if I convert that Zoned date time to UTC using something like:
val utcZoned = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC)
I get (consistently with the error above):
1900-01-01T14:55:28Z
So it's 14:55:28 or what is equivalent to the time 15:15 (3:15 pm) minus 19 minutes and thirty-two seconds.
Am I missing something here?
I'm running this on an Emulator. ZoneId.getSystemDefault() also returns the same ZoneId + Offset. I started hardcoding Amsterdam to see if I could spot a difference.
Another way to see this, is simply by doing:
ZonedDateTime.of(LocalDateTime.of(1900,01,01,15,15,0), ZoneId.of("Europe/Amsterdam")).offset
The result is a ZoneOffset
And consistently with the ninteen minutes above:
The offset is: +00:19:32
What am I doing wrong here?
Did I try java.time.*?
Yes, I removed ThirteenTenABP, and replaced all imports to java.time.* and ran this on an Android O (8.x) to see if the native Java8 time classes would yield a similar result and the answer is: yes.
The offsets come from the offset rules:
But why those numbers?
Looks like that's correct, Amsterdam's timezone used to be based off of the time in Westerkerk.
The reason for the specific offset of +0h 19m 32.13s was that the time zone was centered on the mean solar time of the Westertoren (4° 53' 01.95" E Longitude), the tower of the Westerkerk church in Amsterdam.
https://en.wikipedia.org/wiki/UTC%2B00:20
Bare in mind the docs for ZonedDateTime.of say
The local date-time is then resolved to a single instant on the time-line
So it will give you back a time using the timezone that was in use at that instant in time, not the current timezone in use in the Netherlands.
I have an Asus Fonepad first generation(android 4.1.2) and an Asus Fonepad second generation(android 4.3).
I use the following code to parse the date to the desired format in my app:
SimpleDateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", /*new Locale("nl", "NL")*/Locale.GERMANY);
df.setTimeZone(TimeZone.getTimeZone(/*"Europe/Amsterdam"*/"Europe/Berlin"));
String time = df.format(new Date());
The above code results in "Dez 23 17:09:25 2013" on the first generation fonepad and "Dez. 23 17:09:25 2013" on the second generation fonepad.
As you can see, the second generation adds a dot after the month.
this causes a parsexception on the server side.
Why does SimpleDateFormat behave differently on different devices(android versions)? This is worrying.
Is there a way to always get the same format? What is the solution to this?
Thanks.
SimpleDateFormat (and some other framework classes) use icu4c library to format content. Month format for DE was changed between 49.2 and 50.1 versions of this library.
No, you can't expect same behavior for all android versions.
Link to sources: https://android.googlesource.com/platform/external/icu4c/+/android-4.4.2_r1/data/locales/de.txt
Add: If you sending data to a server than solution is to use only numbers: 12 will be always 12 for December.
I have a program where it relies heavily on identifying the week number for the year. I have done the leg work and figured out all the problems that will cause and settle with this method. I works perfect for years that have 53 weeks and such. My only issue is that when I run it on my emulator for 2.2 it works perfect, like this is week 19 and its correct. when I run it on my phone a G1, the week shows 20. How do I fix this?
Here is my week code:
/**
* Format the date into a number that is the year*100 plus the week i.e. 2008 and its week 11
* would show as 811
* #param - String of a date to create a week id, must be in format of 2011-01-31 (YYYY-MM-DD)
* #return returns next weeks id
*/
public static int getWeekId(String date){
// Set the first day of week to Monday and set the starting new year weeks
// as a full first week in the new year.
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setMinimalDaysInFirstWeek(7);
if (!date.equalsIgnoreCase("")) {
String[] token = date.split("-", 3);
int year = Integer.parseInt(token[0]);
int month = Integer.parseInt(token[1])-1; // months are 0-11 stupid..
int day = Integer.parseInt(token[2]);
c.set(year, month, day);
}
int yearWeek = ( (c.get(Calendar.YEAR) - 2000)*100 + (c.get(Calendar.WEEK_OF_YEAR)));
Log.d("getWeekId()"," WEEK_OF_YEAR: " + c.get(Calendar.WEEK_OF_YEAR));
return yearWeek;
}
(I'd leave this in a comment, but my account does not yet have commenting permissions.)
When called with 2011-01-01, the code currently returns 1152. Is this as intended?
For what it's worth, there is likely more intricacy to it than you've written. I don't say this to be mean, it's just that there are probably lots of interesting weird cases that you haven't considered. There is a good Java library that knows a ton of stuff about times, and may have this code written already, Check it out: http://joda-time.sourceforge.net/
Apparently its a bug in the android phone...so watch out for this when using android 1.6.