From cccc520af8fc1b87f856a1adc4b1ed1fd491dd37 Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Sat, 23 Dec 2017 01:32:08 +0530 Subject: [PATCH 01/11] reformated code to support existing user key an reuse old key. --- .../java/ch/corten/aha/worldclock/UpdateWeatherService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/UpdateWeatherService.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/UpdateWeatherService.java index 0f20306..6259315 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/UpdateWeatherService.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/UpdateWeatherService.java @@ -106,7 +106,7 @@ private int updateData(int updateInterval, long currentTime) { String OWM_API_KEY =prefs.getString(context.getString(R.string.new_api_key),null); Log.e(TAG,"New key from preferance: "+OWM_API_KEY+ "*******************************************************************"); - WeatherService service = new AndroidWeatherServiceFactory().createService("owm",OWM_API_KEY); + WeatherService service = new AndroidWeatherServiceFactory().createService("owm",OWM_API_KEY,context); service.setLanguage(context.getString(R.string.weather_service_language)); try { From 21a334dde28ffca099f75d3de471ace13626c6d6 Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Sat, 23 Dec 2017 01:34:35 +0530 Subject: [PATCH 02/11] added git ignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 36df046..0c79b84 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ gradle.properties .idea/ out/ *.iml + +#key file +/worldclockwidget/default_owm_api_key \ No newline at end of file From b617247d5f4011153da5eb0cbe6d2254f3748311 Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Sat, 23 Dec 2017 01:50:22 +0530 Subject: [PATCH 03/11] rest all --- .../weather/AndroidWeatherServiceFactory.java | 55 +++++++++++++++++-- .../weather/WeatherServiceFactory.java | 4 +- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java index ebfda82..88a21b6 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java @@ -18,10 +18,15 @@ import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.preference.PreferenceManager; +import android.telephony.TelephonyManager; import android.util.Log; import android.view.View; import android.widget.EditText; +import android.widget.Toast; + +import java.util.Random; import ch.corten.aha.worldclock.BuildConfig; import ch.corten.aha.worldclock.R; @@ -32,14 +37,54 @@ public class AndroidWeatherServiceFactory implements WeatherServiceFactory { private static final String TAG = "WeatherServiceFactory"; + private boolean no_key = false; + @Override - public WeatherService createService(String provider,String owm_api_key) { + public WeatherService createService(String provider,String owm_api_key,Context mContext) { + + no_key = false; + String api_key_value=""; + if (BuildConfig.ENABLE_WEATHER) { - Log.e(TAG, "Info:: weather service enabled. Key Value:- "+owm_api_key ); - if (owm_api_key == BuildConfig.OWM_API_KEY) { - Log.e(TAG, "Info:: Currently using default key!!!!!!!!!!!!!!!!!!!!!!!!!!"); + Log.e(TAG,"Default key from default_owm_api_key file: "+BuildConfig.OWM_API_KEY); //This is value from file "default_owm_api_key" + Log.e(TAG, "Info:: weather service enabled."); + //if no key/firsttime then get the default one. + if(owm_api_key == null) + { + Log.e(TAG, "Info:: performance key null detected."); + no_key = true; + } + else if (owm_api_key.equals("Please enter new open weather map API")) + { + Log.e(TAG, "Info:: performance value is: Please enter new open weather map API."); + no_key = true; + } + else if (owm_api_key.trim().length()!=32) + { + Log.e(TAG, "Info:: performance value is not 32 digit."); + no_key = true; } - return new OwmWeatherService(owm_api_key); //Here passing the OWM_API_KEY to the OwmWeatherService class + + if (no_key ){ + Log.e(TAG, "Info:: No key set!!!!!!!!!!!!!!!!!!!!!!!!!! "); + //Trying to get the key from Buildconfig. + String[] OWM_API_KEY_array = BuildConfig.OWM_API_KEY.trim().split(","); + Log.e(TAG, "Info:: Total No of keys:- " + OWM_API_KEY_array.length ); + String new_api_key_from_file = (OWM_API_KEY_array[new Random().nextInt(OWM_API_KEY_array.length)]); + Log.e(TAG, "Info:: New Key:" + new_api_key_from_file+"."); + //Here setting the OWM_API_KEY to the OwmWeatherService class + api_key_value=new_api_key_from_file; + + } + else + { + //always chose from performance key + Log.e(TAG, "Info:: Working key found from performance. Key Value:- " + owm_api_key ); + api_key_value=owm_api_key; + } + + //Finally update all clocks + return new OwmWeatherService(api_key_value); } else { Log.e(TAG, "Warning!!!::Weather service is disabled!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); return new OwmWeatherService(null); diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/WeatherServiceFactory.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/WeatherServiceFactory.java index 58466d1..d211b28 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/WeatherServiceFactory.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/WeatherServiceFactory.java @@ -16,8 +16,10 @@ package ch.corten.aha.worldclock.weather; +import android.content.Context; + public interface WeatherServiceFactory { - WeatherService createService(String provider,String owm_api_key); + WeatherService createService(String provider, String owm_api_key, Context mcontext); } From 44ed30fb4eefd1f1bf591ad1d9ef328b3eaeda95 Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Sat, 23 Dec 2017 02:13:29 +0530 Subject: [PATCH 04/11] Fix for key comparison from performance variable --- .../aha/worldclock/weather/AndroidWeatherServiceFactory.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java index 88a21b6..226a293 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/weather/AndroidWeatherServiceFactory.java @@ -54,7 +54,7 @@ public WeatherService createService(String provider,String owm_api_key,Context m Log.e(TAG, "Info:: performance key null detected."); no_key = true; } - else if (owm_api_key.equals("Please enter new open weather map API")) + else if (owm_api_key.equals("Please enter new open weather map API key")) { Log.e(TAG, "Info:: performance value is: Please enter new open weather map API."); no_key = true; @@ -74,7 +74,6 @@ else if (owm_api_key.trim().length()!=32) Log.e(TAG, "Info:: New Key:" + new_api_key_from_file+"."); //Here setting the OWM_API_KEY to the OwmWeatherService class api_key_value=new_api_key_from_file; - } else { From 8a6c5f154a59d35860422f303f073d8d6d91505a Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Sat, 23 Dec 2017 03:55:22 +0530 Subject: [PATCH 05/11] Added Gangasagar city to application --- README.rst | 6 ++---- worldclockwidget/src/main/assets/city_data.csv | 1 + .../ch/corten/aha/worldclock/provider/CityDatabase.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 2727f23..effda16 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,7 @@ World Clock & Weather ===================== -**This project is coming live again. All the upcoming updates will be mainted by** `Biswajit Das `_ - - -**This new release require Users to signup for API Key. Please look for application Settings -> GENERAL -> !!!Important!!! section** +** Important fix!! +User can use default api key as well as signup API Keys. Please look for application Settings -> GENERAL -> !!!Important!!! section** A simple application to display the local time and current weather conditions in places all over the world. It comes with two home screen widgets which show weather and time or time only. diff --git a/worldclockwidget/src/main/assets/city_data.csv b/worldclockwidget/src/main/assets/city_data.csv index e6700b3..226561b 100644 --- a/worldclockwidget/src/main/assets/city_data.csv +++ b/worldclockwidget/src/main/assets/city_data.csv @@ -1620,6 +1620,7 @@ Kishangarh Kishangarh 26.59006 74.85397 India Asia/Kolkata Kolār Kolar 13.13768 78.12999 India Asia/Kolkata Kolhāpur Kolhapur 16.69563 74.23167 India Asia/Kolkata Kolkata Kolkata 22.56263 88.36304 India Asia/Kolkata +Gangasagar South 24 Parganas 21.647535 88.081215 India Asia/Kolkata Kollam Kollam 8.88113 76.58469 India Asia/Kolkata Korba Korba 22.3458 82.69633 India Asia/Kolkata Kota Kota 25.18254 75.83907 India Asia/Kolkata diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/CityDatabase.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/CityDatabase.java index dd92615..1f6dea5 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/CityDatabase.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/CityDatabase.java @@ -48,8 +48,8 @@ class CityDatabase extends SQLiteOpenHelper { private static final String DROP_TABLE = "drop table if exists cities"; private static final String DATABASE_NAME = "cities"; - private static final int DATABASE_VERSION = 19; - + //private static final int DATABASE_VERSION = 19; + private static final int DATABASE_VERSION = 20; private Context mContext; private boolean mNeedsVacuum; From 6a7c4b84a1f44971d333ef2d0d720126a12eb7e3 Mon Sep 17 00:00:00 2001 From: dasbiswajit Date: Thu, 28 Dec 2017 11:17:35 +0530 Subject: [PATCH 06/11] updated documentation --- .../main/java/ch/corten/aha/worldclock/WorldClockActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java index e5b6eca..d35ae2c 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java @@ -326,6 +326,9 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_add: + //#TODO: Try to add logic find the city from gps and add them below is the example to add the clock + // check if the city is already added then send message already added. + //WorldClock.Clocks.addClock(getActivity(), "Asia/Kolkata", "Gangasagar","India", 330, 21.647535, 88.081215); addClock(); return true; case R.id.menu_refresh: From e07af18c7dd27fe3af6d90f05739048cc704a19f Mon Sep 17 00:00:00 2001 From: Meno Hochschild Date: Fri, 6 Apr 2018 18:15:15 +0200 Subject: [PATCH 07/11] switch from joda to time4a --- README.rst | 2 +- worldclockwidget/build.gradle | 4 +- worldclockwidget/proguard-project.txt | 2 - .../ch/corten/aha/widget/DigitalClock.java | 31 +++-- .../aha/worldclock/AddClockActivity.java | 6 +- .../aha/worldclock/EditClockActivity.java | 4 +- .../java/ch/corten/aha/worldclock/MyApp.java | 4 +- .../corten/aha/worldclock/TimeZoneInfo.java | 108 ++++++++++-------- .../corten/aha/worldclock/WeatherWidget.java | 25 ++-- .../aha/worldclock/WorldClockActivity.java | 12 +- .../worldclock/WorldClockWidgetProvider.java | 15 ++- .../aha/worldclock/provider/WorldClock.java | 6 +- 12 files changed, 119 insertions(+), 100 deletions(-) diff --git a/README.rst b/README.rst index effda16..c9aeab9 100644 --- a/README.rst +++ b/README.rst @@ -53,7 +53,7 @@ The app uses and includes the following libraries: * `ActionBarSherlock `_ (also on `GitHub `__) * `ColorPickerPreference `_ * `google-gson `_ -* `joda-time-android `_ +* `Time4A `_ Acknowledgements ---------------- diff --git a/worldclockwidget/build.gradle b/worldclockwidget/build.gradle index 02aeb47..eb2b45a 100644 --- a/worldclockwidget/build.gradle +++ b/worldclockwidget/build.gradle @@ -90,7 +90,7 @@ def getOpenWeatherMapApiKey() { if (project.hasProperty('owmApiKey')) { return owmApiKey } else { - def apiKeyFile = file('default_owm_api_key'); + def apiKeyFile = file('default_owm_api_key') if (apiKeyFile.isFile()) { return apiKeyFile.text.trim() } @@ -109,7 +109,7 @@ dependencies{ compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' compile 'com.android.support:support-v4:19.1.0' compile 'com.google.code.gson:gson:2.3.1' - compile 'net.danlew:android.joda:2.9.4.1' + compile group: 'net.time4j', name: 'time4j-android', version: '3.41-2018d' } diff --git a/worldclockwidget/proguard-project.txt b/worldclockwidget/proguard-project.txt index 01ebeff..4f30dd8 100644 --- a/worldclockwidget/proguard-project.txt +++ b/worldclockwidget/proguard-project.txt @@ -42,5 +42,3 @@ # public *; #} -# ignore missing Joda time references --dontwarn org.joda.time.tz.ZoneInfoCompiler,org.joda.convert.* diff --git a/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java b/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java index cf0ae1a..21fad40 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java @@ -27,10 +27,12 @@ import android.util.AttributeSet; import android.widget.TextView; -import org.joda.time.DateTimeUtils; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; +import net.time4j.Moment; +import net.time4j.format.expert.ChronoFormatter; +import net.time4j.format.expert.PatternType; +import net.time4j.tz.Timezone; + +import java.util.Locale; /** * Like AnalogClock, but digital. Shows seconds. @@ -57,8 +59,8 @@ public class DigitalClock extends TextView implements PauseListener { private int mState = STATE_DETACHED; private PauseSource mPauseSource = null; - private DateTimeFormatter mDateFormat; - private DateTimeZone mTimeZone; + private ChronoFormatter mDateFormat; + private Timezone mTimeZone; public DigitalClock(Context context) { super(context); @@ -70,11 +72,11 @@ public DigitalClock(Context context, AttributeSet attrs) { initClock(context); } - public DateTimeZone getTimeZone() { + public Timezone getTimeZone() { return mTimeZone; } - public void setTimeZone(DateTimeZone timeZone) { + public void setTimeZone(Timezone timeZone) { mTimeZone = timeZone; setFormat(); updateClock(); @@ -104,7 +106,7 @@ protected void onAttachedToWindow() { super.onAttachedToWindow(); mHandler = new Handler(); - /** + /* * requests a tick on the next hard-second boundary. */ mTicker = new Runnable() { @@ -170,16 +172,21 @@ private boolean is24HourMode() { } private void setFormat() { - mDateFormat = DateTimeFormat.forPattern(is24HourMode() ? M24 : M12).withZone(mTimeZone); + mDateFormat = + ChronoFormatter.ofMomentPattern( + is24HourMode() ? M24 : M12, + PatternType.CLDR, + Locale.getDefault(), + mTimeZone.getID()); } private void updateClock() { - setText(mDateFormat.print(DateTimeUtils.currentTimeMillis())); + setText(mDateFormat.format(net.time4j.SystemClock.currentMoment())); invalidate(); } private class FormatChangeObserver extends ContentObserver { - public FormatChangeObserver() { + FormatChangeObserver() { super(new Handler()); } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java index 8f79f22..fd89a34 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java @@ -40,7 +40,7 @@ import com.actionbarsherlock.widget.SearchView; import com.actionbarsherlock.widget.SearchView.OnQueryTextListener; -import org.joda.time.DateTimeZone; +import net.time4j.tz.Timezone; import ch.corten.aha.worldclock.provider.WorldClock; import ch.corten.aha.worldclock.provider.WorldClock.Cities; @@ -96,7 +96,7 @@ public void bindView(View view, Context context, Cursor cursor) { BindHelper.bindText(view, cursor, R.id.city_text, Cities.NAME); BindHelper.bindText(view, cursor, R.id.area_text, Cities.COUNTRY); TextView timeDiffText = (TextView) view.findViewById(R.id.time_diff_text); - DateTimeZone tz = DateTimeZone.forID(cursor.getString(cursor.getColumnIndex(Cities.TIMEZONE_ID))); + Timezone tz = Timezone.of(cursor.getString(cursor.getColumnIndex(Cities.TIMEZONE_ID))); timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz)); TextView timeZoneDescText = (TextView) view.findViewById(R.id.timezone_desc_text); timeZoneDescText.setText(TimeZoneInfo.getDescription(tz)); @@ -191,7 +191,7 @@ public void onListItemClick(ListView l, View v, int position, long id) { String timeZoneId = c.getString(c.getColumnIndex(Cities.TIMEZONE_ID)); String city = c.getString(c.getColumnIndex(Cities.NAME)); String country = c.getString(c.getColumnIndex(Cities.COUNTRY)); - int timeDiff = TimeZoneInfo.getTimeDifference(DateTimeZone.forID(timeZoneId)); + int timeDiff = TimeZoneInfo.getTimeDifference(Timezone.of(timeZoneId)); double latitude = c.getDouble(c.getColumnIndex(Cities.LATITUDE)); double longitude = c.getDouble(c.getColumnIndex(Cities.LONGITUDE)); WorldClock.Clocks.addClock(getActivity(), timeZoneId, city, diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java index a3a1e4e..cf83326 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java @@ -37,7 +37,7 @@ import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragmentActivity; -import org.joda.time.DateTimeZone; +import net.time4j.tz.Timezone; import ch.corten.aha.worldclock.provider.WorldClock.Clocks; @@ -128,7 +128,7 @@ public void onActivityCreated(Bundle savedInstanceState) { mUseInWidgetCheckBox = (CheckBox) view.findViewById(R.id.use_in_widget_checkbox); mUseInWidgetCheckBox.setChecked(c.getInt(c.getColumnIndex(Clocks.USE_IN_WIDGET)) != 0); String id = c.getString(c.getColumnIndex(Clocks.TIMEZONE_ID)); - DateTimeZone tz = DateTimeZone.forID(id); + Timezone tz = Timezone.of(id); ((TextView) view.findViewById(R.id.time_zone_name)).setText(TimeZoneInfo.getDescription(tz)); ((TextView) view.findViewById(R.id.time_zone_details)).setText(TimeZoneInfo.getTimeDifferenceString(tz)); diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/MyApp.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/MyApp.java index a7fe9e7..2982936 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/MyApp.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/MyApp.java @@ -18,7 +18,7 @@ import android.app.Application; -import net.danlew.android.joda.JodaTimeAndroid; +import net.time4j.android.ApplicationStarter; /** * Initializes libraries. @@ -28,6 +28,6 @@ public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); - JodaTimeAndroid.init(this); + ApplicationStarter.initialize(this); } } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java index 44404b7..ed5447a 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java @@ -16,44 +16,46 @@ package ch.corten.aha.worldclock; -import android.util.Log; - -import org.joda.time.DateTimeUtils; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; +import net.time4j.Moment; +import net.time4j.SystemClock; +import net.time4j.TemporalType; +import net.time4j.base.TimeSource; +import net.time4j.format.expert.ChronoFormatter; +import net.time4j.format.expert.PatternType; +import net.time4j.tz.NameStyle; +import net.time4j.tz.TZID; +import net.time4j.tz.Timezone; +import net.time4j.tz.ZonalOffset; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; +import java.util.Locale; import java.util.TimeZone; public final class TimeZoneInfo { private static final String WEEKDAY_FORMAT = "EEE"; - private static final String TZ_ID_TAG = "TZ-IDs"; private TimeZoneInfo() { } - public static int getTimeDifference(DateTimeZone tz) { - int milliseconds = tz.getOffset(DateTimeUtils.currentTimeMillis()); - return milliseconds / 60000; + public static int getTimeDifference(Timezone tz) { // in minutes + return tz.getOffset(SystemClock.currentMoment()).getIntegralAmount() / 60; } - public static String formatDate(DateFormat dateFormat, DateTimeZone tz, long time) { + public static String formatDate(DateFormat dateFormat, TZID tzid, TimeSource clock) { if (dateFormat instanceof SimpleDateFormat) { String pattern = ((SimpleDateFormat) dateFormat).toPattern(); - DateTimeFormatter format = DateTimeFormat.forPattern(pattern).withZone(tz); - return format.print(time); + ChronoFormatter cf = + ChronoFormatter.ofMomentPattern(pattern, PatternType.CLDR, Locale.getDefault(), tzid); + return cf.format(clock.currentTime()); } else { - dateFormat.setTimeZone(convertToJavaTimeZone(tz, time)); - return dateFormat.format(new Date(time)); + dateFormat.setTimeZone(convertToJavaTimeZone(tzid, clock)); + return dateFormat.format(TemporalType.JAVA_UTIL_DATE.from(clock.currentTime())); } } - public static String getTimeDifferenceString(DateTimeZone tz) { + public static String getTimeDifferenceString(Timezone tz) { int minutesDiff = getTimeDifference(tz); StringBuilder sb = new StringBuilder(); sb.append("UTC"); @@ -76,50 +78,56 @@ public static String getTimeDifferenceString(DateTimeZone tz) { return sb.toString(); } - public static String getDescription(DateTimeZone tz) { - // The Java TimeZones gives a better description (and knows more time zones) - TimeZone timeZone = tz.toTimeZone(); - if (timeZone.useDaylightTime() && timeZone.inDaylightTime(new Date())) { - return timeZone.getDisplayName(true, TimeZone.LONG); - } - return timeZone.getDisplayName(); + public static String getDescription(Timezone tz) { + NameStyle style = + tz.isDaylightSaving(SystemClock.currentMoment()) + ? NameStyle.LONG_DAYLIGHT_TIME + : NameStyle.LONG_STANDARD_TIME; + return tz.getDisplayName(style, Locale.getDefault()); } - public static String showTimeWithOptionalWeekDay(DateTimeZone tz, long time, DateFormat df) { - return formatDate(df, tz, time) + showDifferentWeekday(tz, time); + public static String showTimeWithOptionalWeekDay(TZID tzid, TimeSource clock, DateFormat df) { + return formatDate(df, tzid, clock) + showDifferentWeekday(tzid, clock); } /** - * Convert a joda-time {@link org.joda.time.DateTimeZone} to an equivalent Java {@link java.util.TimeZone}. + * Convert a Time4A {@link net.time4j.tz.Timezone} to an equivalent Java {@link java.util.TimeZone}. * - * @param dateTimeZone a joda-time {@link org.joda.time.DateTimeZone} - * @param time the time when the time zones should be equivalent. + * @param tzid the time zone id + * @param clock source of current time * @return a Java {@link java.util.TimeZone} with the same offset for the given time. */ - public static TimeZone convertToJavaTimeZone(DateTimeZone dateTimeZone, long time) { - TimeZone timeZone = dateTimeZone.toTimeZone(); - long offset = dateTimeZone.getOffset(time); - if (timeZone.getOffset(time) == offset) { + public static TimeZone convertToJavaTimeZone(TZID tzid, TimeSource clock) { + Moment ut = Moment.from(clock.currentTime()); + TimeZone timeZone = TimeZone.getTimeZone(tzid.canonical()); + ZonalOffset offset = Timezone.of(tzid).getOffset(ut); + int platformOffsetInSecs = timeZone.getOffset(ut.getPosixTime() * 1000L) / 1000; + if (platformOffsetInSecs == offset.getIntegralAmount()) { return timeZone; + } else { + // let's now return the simple offset representation + // instead of searching for a potentially wrong replacement zone with same offset + return TimeZone.getTimeZone(offset.canonical()); } - String[] ids = TimeZone.getAvailableIDs((int) offset); - Log.d(TZ_ID_TAG, dateTimeZone.getID() + ": " + Arrays.toString(ids)); - for (String id : ids) { - TimeZone tz = TimeZone.getTimeZone(id); - if (tz.getOffset(time) == offset) { - timeZone = tz; - Log.d(TZ_ID_TAG, "Found time zone " + tz.getID() + " for " + dateTimeZone.getID() + " with offset: " + offset); - break; - } - } - return timeZone; } - public static String showDifferentWeekday(DateTimeZone tz, long time) { - DateTimeFormatter dayFormat = DateTimeFormat.forPattern(WEEKDAY_FORMAT).withZone(tz); - String day = dayFormat.print(time); - DateTimeFormatter localDayFormat = DateTimeFormat.forPattern(WEEKDAY_FORMAT); - if (!day.equals(localDayFormat.print(time))) { + public static String showDifferentWeekday(TZID tzid, TimeSource clock) { + ChronoFormatter dayFormat = + ChronoFormatter.ofMomentPattern( + WEEKDAY_FORMAT, + PatternType.CLDR, + Locale.getDefault(), + tzid); + ChronoFormatter localDayFormat = + ChronoFormatter.ofMomentPattern( + WEEKDAY_FORMAT, + PatternType.CLDR, + Locale.getDefault(), + Timezone.ofSystem().getID()); + Moment now = clock.currentTime(); + String day = dayFormat.format(now); + String localDay = localDayFormat.format(now); + if (!day.equals(localDay)) { return " " + day; } return ""; diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java index 12f42e8..585e2f3 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java @@ -16,24 +16,27 @@ package ch.corten.aha.worldclock; -import java.text.DateFormat; -import java.util.TimeZone; - import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.Bitmap.Config; import android.graphics.PorterDuff.Mode; import android.graphics.drawable.Drawable; import android.os.Build; import android.preference.PreferenceManager; import android.widget.RemoteViews; -import org.joda.time.DateTimeUtils; -import org.joda.time.DateTimeZone; +import net.time4j.Moment; +import net.time4j.SystemClock; +import net.time4j.base.TimeSource; +import net.time4j.tz.TZID; +import net.time4j.tz.Timezone; + +import java.text.DateFormat; +import java.util.TimeZone; import ch.corten.aha.widget.RemoteViewUtil; import ch.corten.aha.worldclock.provider.WorldClock.Clocks; @@ -69,14 +72,14 @@ public static void updateItemView(Context context, Cursor cursor, RemoteViews rv rv.setTextViewText(R.id.city_text, cursor.getString(cursor.getColumnIndex(Clocks.CITY))); String id = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); - long now = DateTimeUtils.currentTimeMillis(); - DateTimeZone tz = DateTimeZone.forID(id); + TZID tzid = Timezone.of(id).getID(); + TimeSource clock = SystemClock.INSTANCE; if (SANS_JELLY_BEAN_MR1) { - rv.setTextViewText(R.id.time_text, TimeZoneInfo.showTimeWithOptionalWeekDay(tz, now, timeFormat)); + rv.setTextViewText(R.id.time_text, TimeZoneInfo.showTimeWithOptionalWeekDay(tzid, clock, timeFormat)); } else { - TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tz, now); + TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, clock); RemoteViewUtil.setTextClockTimeZone(rv, R.id.time_text, javaTimeZone.getID()); - rv.setTextViewText(R.id.weekday_text, TimeZoneInfo.showDifferentWeekday(tz, now)); + rv.setTextViewText(R.id.weekday_text, TimeZoneInfo.showDifferentWeekday(tzid, clock)); } rv.setTextViewText(R.id.condition_text, cursor diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java index d35ae2c..71fd516 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java @@ -49,8 +49,8 @@ import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; -import org.joda.time.DateTimeUtils; -import org.joda.time.DateTimeZone; +import net.time4j.SystemClock; +import net.time4j.tz.Timezone; import java.text.MessageFormat; import java.util.ArrayList; @@ -87,7 +87,7 @@ public static class ClockListFragment extends SherlockListFragment implements private ActionMode mMode; private OnSharedPreferenceChangeListener mSpChange; private boolean mAutoSortClocks; - private final List mListeners = new ArrayList(); + private final List mListeners = new ArrayList<>(); private static final String[] CLOCKS_PROJECTION = { Clocks._ID, @@ -199,7 +199,7 @@ public void addPauseListener(PauseListener listener) { @Override public void removePauseListener(PauseListener listener) { mListeners.remove(listener); - }; + } private void setupCabOld(ListView listView) { listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); @@ -462,10 +462,10 @@ public void bindView(View view, Context context, Cursor cursor) { BindHelper.bindText(view, cursor, R.id.area_text, Clocks.AREA); String timeZoneId = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); - DateTimeZone tz = DateTimeZone.forID(timeZoneId); + Timezone tz = Timezone.of(timeZoneId); java.text.DateFormat df = DateFormat.getDateFormat(context); TextView dateText = (TextView) view.findViewById(R.id.date_text); - dateText.setText(TimeZoneInfo.formatDate(df, tz, DateTimeUtils.currentTimeMillis())); + dateText.setText(TimeZoneInfo.formatDate(df, tz.getID(), SystemClock.INSTANCE)); TextView timeDiffText = (TextView) view.findViewById(R.id.time_diff_text); timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz)); diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java index b71150f..c01f85d 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java @@ -35,8 +35,11 @@ import android.view.View; import android.widget.RemoteViews; -import org.joda.time.DateTimeUtils; -import org.joda.time.DateTimeZone; +import net.time4j.Moment; +import net.time4j.SystemClock; +import net.time4j.base.TimeSource; +import net.time4j.tz.TZID; +import net.time4j.tz.Timezone; public class WorldClockWidgetProvider extends ClockWidgetProvider { private static final boolean SANS_JELLY_BEAN_MR1 = Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1; @@ -94,18 +97,18 @@ private static void updateViews(Context context, RemoteViews views) { try { int n = 0; DateFormat df = android.text.format.DateFormat.getTimeFormat(context); - long now = DateTimeUtils.currentTimeMillis(); final int maxEntries = context.getResources().getInteger(R.integer.worldclock_widget_max_entries); while (cursor.moveToNext() && n < CITY_IDS.length && n < maxEntries) { String id = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); String city = cursor.getString(cursor.getColumnIndex(Clocks.CITY)); views.setTextViewText(CITY_IDS[n], city); - DateTimeZone tz = DateTimeZone.forID(id); + TZID tzid = Timezone.of(id).getID(); + TimeSource clock = SystemClock.INSTANCE; if (SANS_JELLY_BEAN_MR1) { - views.setTextViewText(TIME_IDS[n], TimeZoneInfo.formatDate(df, tz, now)); + views.setTextViewText(TIME_IDS[n], TimeZoneInfo.formatDate(df, tzid, clock)); } else { - TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tz, now); + TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, clock); views.setViewVisibility(TIME_IDS[n], View.VISIBLE); RemoteViewUtil.setTextClockTimeZone(views, TIME_IDS[n], javaTimeZone.getID()); } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java index a084c9f..0cbe4e9 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java @@ -24,7 +24,7 @@ import android.net.Uri; import android.provider.BaseColumns; -import org.joda.time.DateTimeZone; +import net.time4j.tz.Timezone; import ch.corten.aha.worldclock.TimeZoneInfo; import ch.corten.aha.worldclock.weather.WeatherObservation; @@ -38,7 +38,7 @@ private WorldClock() { public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); public static class Clocks implements BaseColumns { - public static enum MoveTarget { + public enum MoveTarget { UP, DOWN } @@ -197,7 +197,7 @@ public static boolean updateOrder(Context context) { while (c.moveToNext()) { String timeZoneId = c.getString(c.getColumnIndex(TIMEZONE_ID)); int storedDiff = c.getInt(c.getColumnIndex(TIME_DIFF)); - DateTimeZone tz = DateTimeZone.forID(timeZoneId); + Timezone tz = Timezone.of(timeZoneId); int diff = TimeZoneInfo.getTimeDifference(tz); if (storedDiff != diff) { // update entry From 14192d04605331833c3f95ee65c9b946f721eced Mon Sep 17 00:00:00 2001 From: Meno Hochschild Date: Sun, 8 Apr 2018 07:24:57 +0200 Subject: [PATCH 08/11] increase clock stability for platforms with outdated tz-data --- .../ch/corten/aha/utils/PlatformClock.java | 29 +++++++++++++++++++ .../ch/corten/aha/widget/DigitalClock.java | 4 ++- .../corten/aha/worldclock/TimeZoneInfo.java | 10 ++++--- .../corten/aha/worldclock/WeatherWidget.java | 4 +-- .../aha/worldclock/WorldClockActivity.java | 4 +-- .../worldclock/WorldClockWidgetProvider.java | 4 +-- 6 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java diff --git a/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java b/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java new file mode 100644 index 0000000..50fa52c --- /dev/null +++ b/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java @@ -0,0 +1,29 @@ +package ch.corten.aha.utils; + +import net.time4j.Moment; +import net.time4j.SystemClock; +import net.time4j.ZonalClock; +import net.time4j.base.TimeSource; + +/** + * A special clock which takes into account possible adjustments of device clock done by app users + * if they intend to compensate wrong platform timezone data. + * + * @author Meno Hochschild + */ +public class PlatformClock + implements TimeSource { + + public static final TimeSource INSTANCE = new PlatformClock(); + + private final ZonalClock zonalClock = SystemClock.inPlatformView(); + + private PlatformClock() { + // singleton constructor + } + + @Override + public Moment currentTime() { + return this.zonalClock.currentMoment(); + } +} diff --git a/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java b/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java index 21fad40..2d094e6 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/widget/DigitalClock.java @@ -34,6 +34,8 @@ import java.util.Locale; +import ch.corten.aha.utils.PlatformClock; + /** * Like AnalogClock, but digital. Shows seconds. * @@ -181,7 +183,7 @@ private void setFormat() { } private void updateClock() { - setText(mDateFormat.format(net.time4j.SystemClock.currentMoment())); + setText(mDateFormat.format(PlatformClock.INSTANCE.currentTime())); invalidate(); } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java index ed5447a..fc2b0f6 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java @@ -17,9 +17,9 @@ package ch.corten.aha.worldclock; import net.time4j.Moment; -import net.time4j.SystemClock; import net.time4j.TemporalType; import net.time4j.base.TimeSource; +import net.time4j.base.UnixTime; import net.time4j.format.expert.ChronoFormatter; import net.time4j.format.expert.PatternType; import net.time4j.tz.NameStyle; @@ -32,6 +32,8 @@ import java.util.Locale; import java.util.TimeZone; +import ch.corten.aha.utils.PlatformClock; + public final class TimeZoneInfo { private static final String WEEKDAY_FORMAT = "EEE"; @@ -40,7 +42,7 @@ private TimeZoneInfo() { } public static int getTimeDifference(Timezone tz) { // in minutes - return tz.getOffset(SystemClock.currentMoment()).getIntegralAmount() / 60; + return tz.getOffset(PlatformClock.INSTANCE.currentTime()).getIntegralAmount() / 60; } public static String formatDate(DateFormat dateFormat, TZID tzid, TimeSource clock) { @@ -80,7 +82,7 @@ public static String getTimeDifferenceString(Timezone tz) { public static String getDescription(Timezone tz) { NameStyle style = - tz.isDaylightSaving(SystemClock.currentMoment()) + tz.isDaylightSaving(PlatformClock.INSTANCE.currentTime()) ? NameStyle.LONG_DAYLIGHT_TIME : NameStyle.LONG_STANDARD_TIME; return tz.getDisplayName(style, Locale.getDefault()); @@ -98,7 +100,7 @@ public static String showTimeWithOptionalWeekDay(TZID tzid, TimeSource c * @return a Java {@link java.util.TimeZone} with the same offset for the given time. */ public static TimeZone convertToJavaTimeZone(TZID tzid, TimeSource clock) { - Moment ut = Moment.from(clock.currentTime()); + UnixTime ut = clock.currentTime(); TimeZone timeZone = TimeZone.getTimeZone(tzid.canonical()); ZonalOffset offset = Timezone.of(tzid).getOffset(ut); int platformOffsetInSecs = timeZone.getOffset(ut.getPosixTime() * 1000L) / 1000; diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java index 585e2f3..d95b00f 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java @@ -30,7 +30,6 @@ import android.widget.RemoteViews; import net.time4j.Moment; -import net.time4j.SystemClock; import net.time4j.base.TimeSource; import net.time4j.tz.TZID; import net.time4j.tz.Timezone; @@ -38,6 +37,7 @@ import java.text.DateFormat; import java.util.TimeZone; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.widget.RemoteViewUtil; import ch.corten.aha.worldclock.provider.WorldClock.Clocks; @@ -73,7 +73,7 @@ public static void updateItemView(Context context, Cursor cursor, RemoteViews rv String id = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); TZID tzid = Timezone.of(id).getID(); - TimeSource clock = SystemClock.INSTANCE; + TimeSource clock = PlatformClock.INSTANCE; if (SANS_JELLY_BEAN_MR1) { rv.setTextViewText(R.id.time_text, TimeZoneInfo.showTimeWithOptionalWeekDay(tzid, clock, timeFormat)); } else { diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java index 71fd516..577afd6 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java @@ -49,13 +49,13 @@ import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; -import net.time4j.SystemClock; import net.time4j.tz.Timezone; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.widget.DigitalClock; import ch.corten.aha.widget.PauseListener; import ch.corten.aha.widget.PauseSource; @@ -465,7 +465,7 @@ public void bindView(View view, Context context, Cursor cursor) { Timezone tz = Timezone.of(timeZoneId); java.text.DateFormat df = DateFormat.getDateFormat(context); TextView dateText = (TextView) view.findViewById(R.id.date_text); - dateText.setText(TimeZoneInfo.formatDate(df, tz.getID(), SystemClock.INSTANCE)); + dateText.setText(TimeZoneInfo.formatDate(df, tz.getID(), PlatformClock.INSTANCE)); TextView timeDiffText = (TextView) view.findViewById(R.id.time_diff_text); timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz)); diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java index c01f85d..eb744cb 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java @@ -19,6 +19,7 @@ import java.text.DateFormat; import java.util.TimeZone; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.widget.RemoteViewUtil; import ch.corten.aha.worldclock.provider.WorldClock.Clocks; @@ -36,7 +37,6 @@ import android.widget.RemoteViews; import net.time4j.Moment; -import net.time4j.SystemClock; import net.time4j.base.TimeSource; import net.time4j.tz.TZID; import net.time4j.tz.Timezone; @@ -104,7 +104,7 @@ private static void updateViews(Context context, RemoteViews views) { String city = cursor.getString(cursor.getColumnIndex(Clocks.CITY)); views.setTextViewText(CITY_IDS[n], city); TZID tzid = Timezone.of(id).getID(); - TimeSource clock = SystemClock.INSTANCE; + TimeSource clock = PlatformClock.INSTANCE; if (SANS_JELLY_BEAN_MR1) { views.setTextViewText(TIME_IDS[n], TimeZoneInfo.formatDate(df, tzid, clock)); } else { From 013c622bac2a27691b336ef31faa11f13218a0e8 Mon Sep 17 00:00:00 2001 From: Meno Hochschild Date: Sun, 8 Apr 2018 14:40:19 +0200 Subject: [PATCH 09/11] avoid multiple calls of current time (refactoring) --- .../aha/worldclock/AddClockActivity.java | 10 ++-- .../aha/worldclock/EditClockActivity.java | 9 +++- .../corten/aha/worldclock/TimeZoneInfo.java | 53 +++++++++---------- .../corten/aha/worldclock/WeatherWidget.java | 9 ++-- .../aha/worldclock/WorldClockActivity.java | 6 ++- .../worldclock/WorldClockWidgetProvider.java | 7 ++- .../aha/worldclock/provider/WorldClock.java | 5 +- 7 files changed, 54 insertions(+), 45 deletions(-) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java index fd89a34..8dcbfca 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/AddClockActivity.java @@ -40,8 +40,10 @@ import com.actionbarsherlock.widget.SearchView; import com.actionbarsherlock.widget.SearchView.OnQueryTextListener; +import net.time4j.Moment; import net.time4j.tz.Timezone; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.worldclock.provider.WorldClock; import ch.corten.aha.worldclock.provider.WorldClock.Cities; @@ -97,9 +99,10 @@ public void bindView(View view, Context context, Cursor cursor) { BindHelper.bindText(view, cursor, R.id.area_text, Cities.COUNTRY); TextView timeDiffText = (TextView) view.findViewById(R.id.time_diff_text); Timezone tz = Timezone.of(cursor.getString(cursor.getColumnIndex(Cities.TIMEZONE_ID))); - timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz)); + Moment moment = PlatformClock.INSTANCE.currentTime(); + timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz, moment)); TextView timeZoneDescText = (TextView) view.findViewById(R.id.timezone_desc_text); - timeZoneDescText.setText(TimeZoneInfo.getDescription(tz)); + timeZoneDescText.setText(TimeZoneInfo.getDescription(tz, moment)); } }; setListAdapter(mAdapter); @@ -191,7 +194,8 @@ public void onListItemClick(ListView l, View v, int position, long id) { String timeZoneId = c.getString(c.getColumnIndex(Cities.TIMEZONE_ID)); String city = c.getString(c.getColumnIndex(Cities.NAME)); String country = c.getString(c.getColumnIndex(Cities.COUNTRY)); - int timeDiff = TimeZoneInfo.getTimeDifference(Timezone.of(timeZoneId)); + Moment moment = PlatformClock.INSTANCE.currentTime(); + int timeDiff = TimeZoneInfo.getTimeDifference(Timezone.of(timeZoneId), moment); double latitude = c.getDouble(c.getColumnIndex(Cities.LATITUDE)); double longitude = c.getDouble(c.getColumnIndex(Cities.LONGITUDE)); WorldClock.Clocks.addClock(getActivity(), timeZoneId, city, diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java index cf83326..bfd1d1f 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/EditClockActivity.java @@ -37,8 +37,10 @@ import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragmentActivity; +import net.time4j.Moment; import net.time4j.tz.Timezone; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.worldclock.provider.WorldClock.Clocks; public class EditClockActivity extends SherlockFragmentActivity { @@ -129,8 +131,11 @@ public void onActivityCreated(Bundle savedInstanceState) { mUseInWidgetCheckBox.setChecked(c.getInt(c.getColumnIndex(Clocks.USE_IN_WIDGET)) != 0); String id = c.getString(c.getColumnIndex(Clocks.TIMEZONE_ID)); Timezone tz = Timezone.of(id); - ((TextView) view.findViewById(R.id.time_zone_name)).setText(TimeZoneInfo.getDescription(tz)); - ((TextView) view.findViewById(R.id.time_zone_details)).setText(TimeZoneInfo.getTimeDifferenceString(tz)); + Moment moment = PlatformClock.INSTANCE.currentTime(); + ((TextView) view.findViewById(R.id.time_zone_name)).setText( + TimeZoneInfo.getDescription(tz, moment)); + ((TextView) view.findViewById(R.id.time_zone_details)).setText( + TimeZoneInfo.getTimeDifferenceString(tz, moment)); if (SANS_ICE_CREAM) { // capitalize text of the checkbox - pre ics does not support textAllCaps. diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java index fc2b0f6..88c10ab 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/TimeZoneInfo.java @@ -18,8 +18,6 @@ import net.time4j.Moment; import net.time4j.TemporalType; -import net.time4j.base.TimeSource; -import net.time4j.base.UnixTime; import net.time4j.format.expert.ChronoFormatter; import net.time4j.format.expert.PatternType; import net.time4j.tz.NameStyle; @@ -32,8 +30,6 @@ import java.util.Locale; import java.util.TimeZone; -import ch.corten.aha.utils.PlatformClock; - public final class TimeZoneInfo { private static final String WEEKDAY_FORMAT = "EEE"; @@ -41,24 +37,27 @@ public final class TimeZoneInfo { private TimeZoneInfo() { } - public static int getTimeDifference(Timezone tz) { // in minutes - return tz.getOffset(PlatformClock.INSTANCE.currentTime()).getIntegralAmount() / 60; + public static int getTimeDifference(Timezone tz, Moment moment) { // in minutes + return tz.getOffset(moment).getIntegralAmount() / 60; } - public static String formatDate(DateFormat dateFormat, TZID tzid, TimeSource clock) { + public static String formatDate(DateFormat dateFormat, TZID tzid, Moment moment) { if (dateFormat instanceof SimpleDateFormat) { String pattern = ((SimpleDateFormat) dateFormat).toPattern(); - ChronoFormatter cf = - ChronoFormatter.ofMomentPattern(pattern, PatternType.CLDR, Locale.getDefault(), tzid); - return cf.format(clock.currentTime()); + return ChronoFormatter.ofMomentPattern( + pattern, + PatternType.CLDR, + Locale.getDefault(), + tzid + ).format(moment); } else { - dateFormat.setTimeZone(convertToJavaTimeZone(tzid, clock)); - return dateFormat.format(TemporalType.JAVA_UTIL_DATE.from(clock.currentTime())); + dateFormat.setTimeZone(convertToJavaTimeZone(tzid, null)); + return dateFormat.format(TemporalType.JAVA_UTIL_DATE.from(moment)); } } - public static String getTimeDifferenceString(Timezone tz) { - int minutesDiff = getTimeDifference(tz); + public static String getTimeDifferenceString(Timezone tz, Moment moment) { + int minutesDiff = getTimeDifference(tz, moment); StringBuilder sb = new StringBuilder(); sb.append("UTC"); if (minutesDiff != 0) { @@ -80,30 +79,29 @@ public static String getTimeDifferenceString(Timezone tz) { return sb.toString(); } - public static String getDescription(Timezone tz) { + public static String getDescription(Timezone tz, Moment moment) { NameStyle style = - tz.isDaylightSaving(PlatformClock.INSTANCE.currentTime()) + tz.isDaylightSaving(moment) ? NameStyle.LONG_DAYLIGHT_TIME : NameStyle.LONG_STANDARD_TIME; return tz.getDisplayName(style, Locale.getDefault()); } - public static String showTimeWithOptionalWeekDay(TZID tzid, TimeSource clock, DateFormat df) { - return formatDate(df, tzid, clock) + showDifferentWeekday(tzid, clock); + public static String showTimeWithOptionalWeekDay(TZID tzid, Moment moment, DateFormat df) { + return formatDate(df, tzid, moment) + showDifferentWeekday(tzid, moment); } /** * Convert a Time4A {@link net.time4j.tz.Timezone} to an equivalent Java {@link java.util.TimeZone}. * - * @param tzid the time zone id - * @param clock source of current time + * @param tzid the time zone id + * @param moment usually the current time * @return a Java {@link java.util.TimeZone} with the same offset for the given time. */ - public static TimeZone convertToJavaTimeZone(TZID tzid, TimeSource clock) { - UnixTime ut = clock.currentTime(); + public static TimeZone convertToJavaTimeZone(TZID tzid, Moment moment) { TimeZone timeZone = TimeZone.getTimeZone(tzid.canonical()); - ZonalOffset offset = Timezone.of(tzid).getOffset(ut); - int platformOffsetInSecs = timeZone.getOffset(ut.getPosixTime() * 1000L) / 1000; + ZonalOffset offset = Timezone.of(tzid).getOffset(moment); + int platformOffsetInSecs = timeZone.getOffset(moment.getPosixTime() * 1000L) / 1000; if (platformOffsetInSecs == offset.getIntegralAmount()) { return timeZone; } else { @@ -113,7 +111,7 @@ public static TimeZone convertToJavaTimeZone(TZID tzid, TimeSource clock) { } } - public static String showDifferentWeekday(TZID tzid, TimeSource clock) { + public static String showDifferentWeekday(TZID tzid, Moment moment) { ChronoFormatter dayFormat = ChronoFormatter.ofMomentPattern( WEEKDAY_FORMAT, @@ -126,9 +124,8 @@ public static String showDifferentWeekday(TZID tzid, TimeSource clock) { PatternType.CLDR, Locale.getDefault(), Timezone.ofSystem().getID()); - Moment now = clock.currentTime(); - String day = dayFormat.format(now); - String localDay = localDayFormat.format(now); + String day = dayFormat.format(moment); + String localDay = localDayFormat.format(moment); if (!day.equals(localDay)) { return " " + day; } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java index d95b00f..161aaa0 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WeatherWidget.java @@ -30,7 +30,6 @@ import android.widget.RemoteViews; import net.time4j.Moment; -import net.time4j.base.TimeSource; import net.time4j.tz.TZID; import net.time4j.tz.Timezone; @@ -73,13 +72,13 @@ public static void updateItemView(Context context, Cursor cursor, RemoteViews rv String id = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); TZID tzid = Timezone.of(id).getID(); - TimeSource clock = PlatformClock.INSTANCE; + Moment moment = PlatformClock.INSTANCE.currentTime(); if (SANS_JELLY_BEAN_MR1) { - rv.setTextViewText(R.id.time_text, TimeZoneInfo.showTimeWithOptionalWeekDay(tzid, clock, timeFormat)); + rv.setTextViewText(R.id.time_text, TimeZoneInfo.showTimeWithOptionalWeekDay(tzid, moment, timeFormat)); } else { - TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, clock); + TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, moment); RemoteViewUtil.setTextClockTimeZone(rv, R.id.time_text, javaTimeZone.getID()); - rv.setTextViewText(R.id.weekday_text, TimeZoneInfo.showDifferentWeekday(tzid, clock)); + rv.setTextViewText(R.id.weekday_text, TimeZoneInfo.showDifferentWeekday(tzid, moment)); } rv.setTextViewText(R.id.condition_text, cursor diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java index 577afd6..1c27fa9 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockActivity.java @@ -49,6 +49,7 @@ import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; +import net.time4j.Moment; import net.time4j.tz.Timezone; import java.text.MessageFormat; @@ -463,12 +464,13 @@ public void bindView(View view, Context context, Cursor cursor) { String timeZoneId = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); Timezone tz = Timezone.of(timeZoneId); + Moment moment = PlatformClock.INSTANCE.currentTime(); java.text.DateFormat df = DateFormat.getDateFormat(context); TextView dateText = (TextView) view.findViewById(R.id.date_text); - dateText.setText(TimeZoneInfo.formatDate(df, tz.getID(), PlatformClock.INSTANCE)); + dateText.setText(TimeZoneInfo.formatDate(df, tz.getID(), moment)); TextView timeDiffText = (TextView) view.findViewById(R.id.time_diff_text); - timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz)); + timeDiffText.setText(TimeZoneInfo.getTimeDifferenceString(tz, moment)); DigitalClock clock = (DigitalClock) view.findViewById(R.id.time_clock); clock.setTimeZone(tz); diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java index eb744cb..bbcfb31 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/WorldClockWidgetProvider.java @@ -37,7 +37,6 @@ import android.widget.RemoteViews; import net.time4j.Moment; -import net.time4j.base.TimeSource; import net.time4j.tz.TZID; import net.time4j.tz.Timezone; @@ -98,17 +97,17 @@ private static void updateViews(Context context, RemoteViews views) { int n = 0; DateFormat df = android.text.format.DateFormat.getTimeFormat(context); final int maxEntries = context.getResources().getInteger(R.integer.worldclock_widget_max_entries); + Moment moment = PlatformClock.INSTANCE.currentTime(); while (cursor.moveToNext() && n < CITY_IDS.length && n < maxEntries) { String id = cursor.getString(cursor.getColumnIndex(Clocks.TIMEZONE_ID)); String city = cursor.getString(cursor.getColumnIndex(Clocks.CITY)); views.setTextViewText(CITY_IDS[n], city); TZID tzid = Timezone.of(id).getID(); - TimeSource clock = PlatformClock.INSTANCE; if (SANS_JELLY_BEAN_MR1) { - views.setTextViewText(TIME_IDS[n], TimeZoneInfo.formatDate(df, tzid, clock)); + views.setTextViewText(TIME_IDS[n], TimeZoneInfo.formatDate(df, tzid, moment)); } else { - TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, clock); + TimeZone javaTimeZone = TimeZoneInfo.convertToJavaTimeZone(tzid, moment); views.setViewVisibility(TIME_IDS[n], View.VISIBLE); RemoteViewUtil.setTextClockTimeZone(views, TIME_IDS[n], javaTimeZone.getID()); } diff --git a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java index 0cbe4e9..3666c08 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/worldclock/provider/WorldClock.java @@ -24,8 +24,10 @@ import android.net.Uri; import android.provider.BaseColumns; +import net.time4j.Moment; import net.time4j.tz.Timezone; +import ch.corten.aha.utils.PlatformClock; import ch.corten.aha.worldclock.TimeZoneInfo; import ch.corten.aha.worldclock.weather.WeatherObservation; @@ -194,11 +196,12 @@ public static boolean updateOrder(Context context) { Cursor c = cr.query(CONTENT_URI, new String[] {_ID, TIMEZONE_ID, TIME_DIFF}, null, null, _ID); if (c != null) { try { + Moment moment = PlatformClock.INSTANCE.currentTime(); while (c.moveToNext()) { String timeZoneId = c.getString(c.getColumnIndex(TIMEZONE_ID)); int storedDiff = c.getInt(c.getColumnIndex(TIME_DIFF)); Timezone tz = Timezone.of(timeZoneId); - int diff = TimeZoneInfo.getTimeDifference(tz); + int diff = TimeZoneInfo.getTimeDifference(tz, moment); if (storedDiff != diff) { // update entry long id = c.getLong(c.getColumnIndex(_ID)); From 46bccdf40a8c95e46c8a122688baa54a547c26ab Mon Sep 17 00:00:00 2001 From: Meno Hochschild Date: Fri, 2 Nov 2018 03:44:22 +0100 Subject: [PATCH 10/11] version update of Time4A-dependency --- worldclockwidget/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldclockwidget/build.gradle b/worldclockwidget/build.gradle index eb2b45a..f59f5f0 100644 --- a/worldclockwidget/build.gradle +++ b/worldclockwidget/build.gradle @@ -109,7 +109,7 @@ dependencies{ compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' compile 'com.android.support:support-v4:19.1.0' compile 'com.google.code.gson:gson:2.3.1' - compile group: 'net.time4j', name: 'time4j-android', version: '3.41-2018d' + compile group: 'net.time4j', name: 'time4j-android', version: '4.0-2018g' } From 1642c08a7a363f80fd23dc4042d2a8c6747a4ff5 Mon Sep 17 00:00:00 2001 From: Meno Hochschild Date: Fri, 2 Nov 2018 03:52:21 +0100 Subject: [PATCH 11/11] fix for outdated method was removed in Time4A-v4.0 --- .../src/main/java/ch/corten/aha/utils/PlatformClock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java b/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java index 50fa52c..e6c530d 100644 --- a/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java +++ b/worldclockwidget/src/main/java/ch/corten/aha/utils/PlatformClock.java @@ -24,6 +24,6 @@ private PlatformClock() { @Override public Moment currentTime() { - return this.zonalClock.currentMoment(); + return this.zonalClock.now().inStdTimezone(); } }