JodaTime will always change to 2015 if withYear set to 2016 - android

This is really driving me crazy. The code below
DateTime dt = new DateTime()
.withYear(2014)
.withWeekOfWeekyear(52)
.withDayOfWeek(1);
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("d MMM yyyy");
String firstDayOfWeek = dateTimeFormatter.print(dt);
Log.v(FILE_NAME,"display date? " + firstDayOfWeek);
dt = new DateTime()
.withYear(2015)
.withWeekOfWeekyear(52)
.withDayOfWeek(1);
String lastDayOfWeek = dateTimeFormatter.print(dt);
Log.v(FILE_NAME,"display date? " + lastDayOfWeek);
dt = new DateTime()
.withYear(2016)
.withWeekOfWeekyear(52)
.withDayOfWeek(1);
lastDayOfWeek = dateTimeFormatter.print(dt);
Log.v(FILE_NAME,"display date? " + lastDayOfWeek);
Somehow will always output:
display date? 22 Dec 2014
display date? 21 Dec 2015
display date? 21 Dec 2015
As you can see, the last display date should display 2016, not 2015. It seems that everytime I set withYear to 2016, it will magically change to 2015. Is this a bug or am I doing something wrong? I have cleaned and rebuild my project many times but the output is the same.

The method withYear(...) does not do what you think because it uses the standard calendar year and not the year of week date as described in ISO-8601-paper. Please compare following two snippets. Only the second one does what you need:
DateTime dt = new DateTime().withYear(2016).withWeekOfWeekyear(52).withDayOfWeek(1);
System.out.println("joda=" + dt); // joda=2015-12-21T18:26:12.776+01:00
DateTime dt2 =
new DateTime().withWeekyear(2016).withWeekOfWeekyear(52).withDayOfWeek(1);
System.out.println("joda=" + dt2); // joda=2016-12-26T18:27:59.606+01:00
See also the documentation. The fine difference between calendar year and weekbased year is only noticeable at the end or start of a year (like today).
Explained in detail the behaviour:
If choosing new DateTime() for today, the second of January 2017 and then setting the calendar year to 2016 results in: 2016-01-02. But this date is in week-of-year 53 belonging to week-based-year 2015. This 53rd week starts on 2015-12-28, so the expression withWeekOfWeekyear(52) will go back one week to 2015-12-21 (what you observe in first case).

Related

Chinese New Year Date on Android

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

Android getRelativeTimeSpanString not working

I am working on notifications and I need to display the time-> An action was performed in a way similar to ("5 seconds ago","12 mins ago","1 week ago" etc.)
This is the code I am using
long now = System.currentTimeMillis();
String datetime1 = "06/12/2015 03:58 PM";
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm aa");
Date convertedDate = dateFormat.parse(datetime1);
CharSequence relavetime1 = DateUtils.getRelativeTimeSpanString(
convertedDate.getTime(),
now,
DateUtils.SECOND_IN_MILLIS,
DateUtils.FORMAT_ABBREV_RELATIVE);
And the result I get is
relativetime1=June 12, 2015
The above obtained result doesn't seem like what its supposed to look like.
By searching online I've found that if that duration is greater than a week, in which case it returns an ABSOLUTE
-I don't quite understand what I found.
How do I achieve my requirement without using an external library?
Kindly help.

Custom Android date formatting respecting current Locale

Is there a way how to specify dateFormat elements and respect current locale rules? I know that I can use SimpleDateFormat and specify the format I like - but it may be wrong in different country.
I tried to mask the elements in DateFormat but it accepts only SHORT, MEDIUM and LONG:
DateFormat dayMonth = DateFormat.getDateInstance(DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD | DateFormat.MONTH_FIELD);
Caused by: java.lang.IllegalArgumentException: Illegal date style: 11
at java.text.DateFormat.checkDateStyle(DateFormat.java:843)
at java.text.DateFormat.getDateInstance(DateFormat.java:378)
I want to get "Oct 2016", or "Říj 2016". This can be implemented with:
DateFormat dayMonth = new SimpleDateFormat("MMM yyyy");
But I do not want to hard code this format in my app. I see one way only: put it into strings.xml and a translator will have to set it up. Or is there better way?
Android has DateFormat.getBestDateTimePattern() to achieve this
pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "MMMyyyy");
dayMonth = new SimpleDateFormat(pattern);
The only downside is the API level of 18. I personally used the result of DateFormat.getMediumDateFormat() as fallback. Alternatively you could just ignore the locale for older devices and use new SimpleDateFormat("MMM yyyy") there as fallback or try to backport this one method.
OP Edit
I tried on Nexus 5x with Android 6 a following code
for (Locale locale : locales) {
format = android.text.format.DateFormat.getBestDateTimePattern(locale, "MMMyyyy");
DateFormat dateFormat = new SimpleDateFormat(format, locale);
log.debug("{}: {}", locale.getCountry(), dateFormat.format(new Date()));
}
And here are some result:
NA: Jul 2016
AE: يوليو ٢٠١٦
BG: 07.2016 г.
CZ: červenec 2016
FR: Goue 2016
DE: Juli 2016
GB: Jul 2016
FI: heinä 2016
IT: Lui 2016
HR: srp 2016.
RU: июль 2016

Convert GMT date to IST

I am trying to convert GMT time to IST using the following piece of code:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2015-01-25");
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
Log.d("date",sdf.format(date1));
However, 2015-01-24 is being logged out in console.Where am i wrong?
Since you are on IST, you have to manually specify GMT. Like this,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("GMT")); // set this if your timezone is different
Date date1 = sdf.parse("2015-01-25"); // now time is Sun Jan 25 00:00:00 GMT 2015
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
Log.d("date",sdf.format(date1)); // now time is Sun Jan 25 05:30:00 IST 2015
Since IST = GMT + 05.30, you will get the same date.
The code snippet converts 2015-01-25 00:00:00 local time (whatever that is - seems to be east of IST) to IST and prints the date part of it.
So 2015-01-26 can never be output as IST would have to be at least 24 hours ahead of local time.

Calendar.WEEK_OF_MONTH gives different results on two different devices

I have two devices HTC with android 2.3.5 and Samsung with 2.3.6
now the problem i am facing is
i need the date's week of month.
So i've written this code and installed on both the phones. and set the system date as
27th Jan 2013
Calendar calendar = Calendar.getInstance();
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
Log.i(TAG,"weekOfMonth = "+weekOfMonth);
now on HTC the output is
weekOfMonth = 5
while on samsung running the same code produces
weekOfMonth = 4
this really is screwing my logic n calculations ahead.
am i doing something wrong ?
It is probably due to Locales. In Java
Calendar calFr = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), Locale.FRANCE);
Calendar calUs = Calendar.getInstance(TimeZone.getTimeZone("US/Eastern"), Locale.US);
Calendar calUk = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.UK);
calFr.set(2013, Calendar.JANUARY, 27);
calUs.set(2013, Calendar.JANUARY, 27);
calUk.set(2013, Calendar.JANUARY, 27);
int weekOfMonthFr = calFr.get(Calendar.WEEK_OF_MONTH);
int weekOfMonthUs = calUs.get(Calendar.WEEK_OF_MONTH);
int weekOfMonthUk = calUk.get(Calendar.WEEK_OF_MONTH);
System.out.println("France week of month is " + weekOfMonthFr);
System.out.println("USA week of month is " + weekOfMonthUs);
System.out.println("UK week of month is " + weekOfMonthUk);
will give you
France week of month is 4
USA week of month is 5
UK week of month is 4
Double check the year that it is set to, if one is set to 2012 and the other 2013, that would explain the difference.
Can you get the applications to log the date held in the calendar object and post it here as well just to make sure they have correct information.

Categories

Resources