From 86e1e97f085d5184d0e9cee30d89aff9109df30b Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Thu, 9 Nov 2017 20:09:14 +0100 Subject: [PATCH] Unify date and time handling * Present date in the "medium" (default) format (e.g. Nov 9, 2017) instead of dd.MM.YYYY (e.g. 09.11.2017). Besides that it is easier to read and wraps better in the table view, it is also localized and avoids the uncertainty if day or month comes first. * Similar, time is now presented in a localized format (i.e. 12 or 24 hour clock is taken from system settings). * The time pickers are also configured to show a 12 or 24 hour clock depending on the system setting. * Handling of birthday and goal date is now fully done in the user settings activity and OpenScale.(add|update)ScaleUser no longer has to know which format the date string was in. * The date and time measurement view now opens the date/time picker with the initial date/time set to the measurement's value. --- .../com/health/openscale/core/OpenScale.java | 48 ++++++------- .../openscale/core/datatypes/ScaleData.java | 14 ---- .../gui/activities/DataEntryActivity.java | 49 ++++++++------ .../gui/activities/UserSettingsActivity.java | 67 +++++++++++-------- .../gui/preferences/TimePreferenceDialog.java | 9 ++- .../gui/views/DateMeasurementView.java | 14 ++-- .../openscale/gui/views/MeasurementView.java | 2 + .../gui/views/TimeMeasurementView.java | 18 +++-- .../main/res/layout/activity_usersettings.xml | 2 + 9 files changed, 119 insertions(+), 104 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 76c4b0dc..d60b178a 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -46,6 +46,7 @@ import java.io.OutputStreamWriter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.Map; import java.util.TreeMap; @@ -86,23 +87,18 @@ public class OpenScale { return instance; } - public void addScaleUser(String name, String birthday, int body_height, int scale_unit, int gender, float initial_weight, float goal_weight, String goal_date) + public void addScaleUser(String name, Date birthday, int body_height, int scale_unit, int gender, float initial_weight, float goal_weight, Date goal_date) { ScaleUser scaleUser = new ScaleUser(); - try { - scaleUser.user_name = name; - scaleUser.birthday = new SimpleDateFormat("dd.MM.yyyy").parse(birthday); - scaleUser.body_height = body_height; - scaleUser.scale_unit = scale_unit; - scaleUser.gender = gender; - scaleUser.setConvertedInitialWeight(initial_weight); - scaleUser.goal_weight = goal_weight; - scaleUser.goal_date = new SimpleDateFormat("dd.MM.yyyy").parse(goal_date); - - } catch (ParseException e) { - Log.e("OpenScale", "Can't parse date time string while adding to the database"); - } + scaleUser.user_name = name; + scaleUser.birthday = birthday; + scaleUser.body_height = body_height; + scaleUser.scale_unit = scale_unit; + scaleUser.gender = gender; + scaleUser.setConvertedInitialWeight(initial_weight); + scaleUser.goal_weight = goal_weight; + scaleUser.goal_date = goal_date; scaleUserDB.insertEntry(scaleUser); } @@ -142,23 +138,19 @@ public class OpenScale { scaleUserDB.deleteEntry(id); } - public void updateScaleUser(int id, String name, String birthday, int body_height, int scale_unit, int gender, float initial_weight, float goal_weight, String goal_date) + public void updateScaleUser(int id, String name, Date birthday, int body_height, int scale_unit, int gender, float initial_weight, float goal_weight, Date goal_date) { ScaleUser scaleUser = new ScaleUser(); - try { - scaleUser.id = id; - scaleUser.user_name = name; - scaleUser.birthday = new SimpleDateFormat("dd.MM.yyyy").parse(birthday); - scaleUser.body_height = body_height; - scaleUser.scale_unit = scale_unit; - scaleUser.gender = gender; - scaleUser.setConvertedInitialWeight(initial_weight); - scaleUser.goal_weight = goal_weight; - scaleUser.goal_date = new SimpleDateFormat("dd.MM.yyyy").parse(goal_date); - } catch (ParseException e) { - Log.e("OpenScale", "Can't parse date time string while adding to the database"); - } + scaleUser.id = id; + scaleUser.user_name = name; + scaleUser.birthday = birthday; + scaleUser.body_height = body_height; + scaleUser.scale_unit = scale_unit; + scaleUser.gender = gender; + scaleUser.setConvertedInitialWeight(initial_weight); + scaleUser.goal_weight = goal_weight; + scaleUser.goal_date = goal_date; scaleUserDB.updateScaleUser(scaleUser); } diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java index de85e168..bcc3296f 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java @@ -16,18 +16,12 @@ package com.health.openscale.core.datatypes; -import android.util.Log; - -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Date; public class ScaleData { private static float KG_LB = 2.20462f; private static float KG_ST = 0.157473f; - private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); - private long id; private int user_id; private Date date_time; @@ -81,14 +75,6 @@ public class ScaleData { this.date_time = date_time; } - public void setDateTime(String date_time) { - try { - this.date_time = dateTimeFormat.parse(date_time); - } catch (ParseException e) { - Log.e("OpenScale", "Can't parse date time string while adding to the database"); - } - } - public float getWeight() { return weight; } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java index 31bc5464..314c24f3 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java @@ -34,6 +34,7 @@ import android.widget.Toast; import com.health.openscale.R; import com.health.openscale.core.OpenScale; import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; import com.health.openscale.gui.views.BMIMeasurementView; import com.health.openscale.gui.views.BMRMeasurementView; import com.health.openscale.gui.views.BoneMeasurementView; @@ -53,6 +54,7 @@ import com.health.openscale.gui.views.WeightMeasurementView; import java.text.DateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collections; import java.util.Date; @@ -280,15 +282,24 @@ public class DataEntryActivity extends Activity { } } - private void saveScaleData() { + private ScaleData createScaleDataFromMeasurement() { OpenScale openScale = OpenScale.getInstance(getApplicationContext()); + ScaleUser user = openScale.getSelectedScaleUser(); + + Calendar time = Calendar.getInstance(); + time.setTime(timeMeasurement.getDateTime()); + + Calendar cal = Calendar.getInstance(); + cal.setTime(dateMeasurement.getDateTime()); + cal.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY)); + cal.set(Calendar.MINUTE, time.get(Calendar.MINUTE)); + cal.set(Calendar.SECOND, time.get(Calendar.SECOND)); ScaleData scaleData = new ScaleData(); - scaleData.setId(id); - scaleData.setUserId(openScale.getSelectedScaleUser().id); - scaleData.setDateTime(dateMeasurement.getValueAsString() + " " + timeMeasurement.getValueAsString()); - scaleData.setConvertedWeight(weightMeasurement.getValue(), openScale.getSelectedScaleUser().scale_unit); + scaleData.setUserId(user.id); + scaleData.setDateTime(cal.getTime()); + scaleData.setConvertedWeight(weightMeasurement.getValue(), user.scale_unit); scaleData.setFat(fatMeasurement.getValue()); scaleData.setWater(waterMeasurement.getValue()); scaleData.setMuscle(muscleMeasurement.getValue()); @@ -298,6 +309,15 @@ public class DataEntryActivity extends Activity { scaleData.setBone(boneMeasurementView.getValue()); scaleData.setComment(commentMeasurement.getValueAsString()); + return scaleData; + } + + private void saveScaleData() { + ScaleData scaleData = createScaleDataFromMeasurement(); + + scaleData.setId(id); + + OpenScale openScale = OpenScale.getInstance(getApplicationContext()); openScale.updateScaleData(scaleData); } @@ -334,10 +354,8 @@ public class DataEntryActivity extends Activity { private class onClickListenerAdd implements View.OnClickListener { @Override public void onClick(View v) { - OpenScale openScale = OpenScale.getInstance(getApplicationContext()); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int selectedUserId = prefs.getInt("selectedUserId", -1); + int selectedUserId = prefs.getInt("selectedUserId", -1); if (selectedUserId == -1) { AlertDialog.Builder infoDialog = new AlertDialog.Builder(context); @@ -348,20 +366,9 @@ public class DataEntryActivity extends Activity { infoDialog.show(); } else { - ScaleData scaleData = new ScaleData(); - - scaleData.setUserId(selectedUserId); - scaleData.setDateTime( dateMeasurement.getValueAsString() + " " + timeMeasurement.getValueAsString()); - scaleData.setConvertedWeight(weightMeasurement.getValue(), openScale.getSelectedScaleUser().scale_unit); - scaleData.setFat(fatMeasurement.getValue()); - scaleData.setWater(waterMeasurement.getValue()); - scaleData.setMuscle(muscleMeasurement.getValue()); - scaleData.setLBW(lbwMeasurement.getValue()); - scaleData.setWaist(waistMeasurement.getValue()); - scaleData.setHip(hipMeasurement.getValue()); - scaleData.setBone(boneMeasurementView.getValue()); - scaleData.setComment(commentMeasurement.getValueAsString()); + ScaleData scaleData = createScaleDataFromMeasurement(); + OpenScale openScale = OpenScale.getInstance(getApplicationContext()); openScale.addScaleData(scaleData); finish(); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java index d434617a..e7cd1af4 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java @@ -35,7 +35,7 @@ import com.health.openscale.R; import com.health.openscale.core.OpenScale; import com.health.openscale.core.datatypes.ScaleUser; -import java.text.SimpleDateFormat; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -45,6 +45,9 @@ public class UserSettingsActivity extends Activity { public static final int ADD_USER_REQUEST = 0; public static final int EDIT_USER_REQUEST = 1; + private Date birthday = new Date(); + private Date goal_date = new Date(); + private EditText txtUserName; private EditText txtBodyHeight; private EditText txtBirthday; @@ -58,7 +61,7 @@ public class UserSettingsActivity extends Activity { private Button btnCancel; private Button btnDelete; - private SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); + private DateFormat dateFormat = DateFormat.getDateInstance(); private Context context; @@ -86,28 +89,30 @@ public class UserSettingsActivity extends Activity { btnCancel.setOnClickListener(new onClickListenerCancel()); btnDelete.setOnClickListener(new onClickListenerDelete()); - txtBirthday.setText(dateFormat.format(new Date())); - txtGoalDate.setText(dateFormat.format(new Date())); + txtBirthday.setText(dateFormat.format(birthday)); + txtGoalDate.setText(dateFormat.format(goal_date)); - txtBirthday.setOnFocusChangeListener(new View.OnFocusChangeListener() { + txtBirthday.setOnClickListener(new View.OnClickListener() { @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - Calendar cal = Calendar.getInstance(); - DatePickerDialog datePicker = new DatePickerDialog(context, datePickerListener, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); - datePicker.show(); - } + public void onClick(View v) { + Calendar cal = Calendar.getInstance(); + cal.setTime(birthday); + DatePickerDialog datePicker = new DatePickerDialog( + context, birthdayPickerListener, cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + datePicker.show(); } }); - txtGoalDate.setOnFocusChangeListener(new View.OnFocusChangeListener() { + txtGoalDate.setOnClickListener(new View.OnClickListener() { @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - Calendar cal = Calendar.getInstance(); - DatePickerDialog datePicker = new DatePickerDialog(context, goalDatePickerListener, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); - datePicker.show(); - } + public void onClick(View v) { + Calendar cal = Calendar.getInstance(); + cal.setTime(goal_date); + DatePickerDialog datePicker = new DatePickerDialog( + context, goalDatePickerListener, cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + datePicker.show(); } }); @@ -130,10 +135,13 @@ public class UserSettingsActivity extends Activity { ScaleUser scaleUser = openScale.getScaleUser(id); + birthday = scaleUser.birthday; + goal_date = scaleUser.goal_date; + txtUserName.setText(scaleUser.user_name); txtBodyHeight.setText(Integer.toString(scaleUser.body_height)); - txtBirthday.setText(dateFormat.format(scaleUser.birthday)); - txtGoalDate.setText(dateFormat.format(scaleUser.goal_date)); + txtBirthday.setText(dateFormat.format(birthday)); + txtGoalDate.setText(dateFormat.format(goal_date)); txtInitialWeight.setText(Math.round(scaleUser.getConvertedInitialWeight()*100.0f)/100.0f + ""); txtGoalWeight.setText(scaleUser.goal_weight+""); @@ -192,17 +200,23 @@ public class UserSettingsActivity extends Activity { return validate; } - private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() { + private DatePickerDialog.OnDateSetListener birthdayPickerListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) { - txtBirthday.setText(String.format("%02d.%02d.%04d", selectedDay, selectedMonth + 1, selectedYear)); + Calendar cal = Calendar.getInstance(); + cal.set(selectedYear, selectedMonth, selectedDay, 0, 0, 0); + birthday = cal.getTime(); + txtBirthday.setText(dateFormat.format(birthday)); } }; private DatePickerDialog.OnDateSetListener goalDatePickerListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) { - txtGoalDate.setText(String.format("%02d.%02d.%04d", selectedDay, selectedMonth + 1, selectedYear)); + Calendar cal = Calendar.getInstance(); + cal.set(selectedYear, selectedMonth, selectedDay, 0, 0, 0); + goal_date = cal.getTime(); + txtGoalDate.setText(dateFormat.format(goal_date)); } }; @@ -290,16 +304,13 @@ public class UserSettingsActivity extends Activity { break; } - String date = txtBirthday.getText().toString(); - String goal_date = txtGoalDate.getText().toString(); - int id = 0; if (getIntent().getExtras().getInt("mode") == EDIT_USER_REQUEST) { id = getIntent().getExtras().getInt("id"); - openScale.updateScaleUser(id, name, date, body_height, scale_unit, gender, initial_weight, goal_weight, goal_date); + openScale.updateScaleUser(id, name, birthday, body_height, scale_unit, gender, initial_weight, goal_weight, goal_date); } else { - openScale.addScaleUser(name, date, body_height, scale_unit, gender, initial_weight, goal_weight, goal_date); + openScale.addScaleUser(name, birthday, body_height, scale_unit, gender, initial_weight, goal_weight, goal_date); id = openScale.getScaleUserList().get(openScale.getScaleUserList().size() - 1).id; } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/TimePreferenceDialog.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/TimePreferenceDialog.java index a3f9c73a..9d7b6df1 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/TimePreferenceDialog.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/TimePreferenceDialog.java @@ -26,8 +26,6 @@ import android.widget.TimePicker; import com.health.openscale.R; import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; public class TimePreferenceDialog extends DialogPreference { private Calendar calendar; @@ -46,13 +44,14 @@ public class TimePreferenceDialog extends DialogPreference { setPositiveButtonText(R.string.label_ok); setNegativeButtonText(R.string.label_cancel); - calendar = new GregorianCalendar(); + calendar = Calendar.getInstance(); } @Override protected View onCreateDialogView() { picker = new TimePicker(getContext()); - return (picker); + picker.setIs24HourView(android.text.format.DateFormat.is24HourFormat(getContext())); + return picker; } @Override @@ -107,7 +106,7 @@ public class TimePreferenceDialog extends DialogPreference { if (calendar == null) { return null; } - return DateFormat.getTimeFormat(getContext()).format(new Date(calendar.getTimeInMillis())); + return DateFormat.getTimeFormat(getContext()).format(calendar.getTime()); } public long getTimeInMillis() { diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java index 6a176efd..2a993e38 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java @@ -27,12 +27,12 @@ import com.health.openscale.core.datatypes.ScaleData; import com.health.openscale.core.evaluation.EvaluationResult; import com.health.openscale.core.evaluation.EvaluationSheet; -import java.text.SimpleDateFormat; +import java.text.DateFormat; import java.util.Calendar; import java.util.Date; public class DateMeasurementView extends MeasurementView { - private SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); + private DateFormat dateFormat = DateFormat.getDateInstance(); public DateMeasurementView(Context context) { super(context, context.getResources().getString(R.string.label_date), ContextCompat.getDrawable(context, R.drawable.ic_lastmonth)); @@ -41,15 +41,21 @@ public class DateMeasurementView extends MeasurementView { private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) { - setValueOnView(new Date(), String.format("%02d.%02d.%04d", selectedDay, selectedMonth+1, selectedYear)); + Calendar cal = Calendar.getInstance(); + cal.set(selectedYear, selectedMonth, selectedDay); + Date date = cal.getTime(); + setValueOnView(date, dateFormat.format(date)); } }; @Override protected AlertDialog getInputDialog() { Calendar cal = Calendar.getInstance(); + cal.setTime(getDateTime()); - DatePickerDialog datePicker = new DatePickerDialog(getContext(), datePickerListener, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + DatePickerDialog datePicker = new DatePickerDialog( + getContext(), datePickerListener, cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); return datePicker; } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java index f9878422..10fafc3f 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java @@ -243,6 +243,8 @@ public abstract class MeasurementView extends TableLayout { public String getDiffValue() { return diffValue; } + public Date getDateTime() { return dateTime; } + protected boolean isEditable() { return true; } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java index f7bb780c..302201fd 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java @@ -27,29 +27,39 @@ import com.health.openscale.core.datatypes.ScaleData; import com.health.openscale.core.evaluation.EvaluationResult; import com.health.openscale.core.evaluation.EvaluationSheet; -import java.text.SimpleDateFormat; +import java.text.DateFormat; import java.util.Calendar; import java.util.Date; public class TimeMeasurementView extends MeasurementView { - private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); + private DateFormat timeFormat; public TimeMeasurementView(Context context) { super(context, context.getResources().getString(R.string.label_time), ContextCompat.getDrawable(context, R.drawable.ic_daysleft)); + timeFormat = android.text.format.DateFormat.getTimeFormat(context); } private TimePickerDialog.OnTimeSetListener timePickerListener = new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { - setValueOnView(new Date(), String.format("%02d:%02d", hourOfDay, minute)); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, hourOfDay); + cal.set(Calendar.MINUTE, minute); + cal.set(Calendar.SECOND, 0); + Date date = cal.getTime(); + setValueOnView(date, timeFormat.format(date)); } }; @Override protected AlertDialog getInputDialog() { Calendar cal = Calendar.getInstance(); + cal.setTime(getDateTime()); - TimePickerDialog timePicker = new TimePickerDialog(getContext(), timePickerListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true); + TimePickerDialog timePicker = new TimePickerDialog( + getContext(), timePickerListener, + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + android.text.format.DateFormat.is24HourFormat(getContext())); return timePicker; } diff --git a/android_app/app/src/main/res/layout/activity_usersettings.xml b/android_app/app/src/main/res/layout/activity_usersettings.xml index 964b6a91..10c5f0ed 100644 --- a/android_app/app/src/main/res/layout/activity_usersettings.xml +++ b/android_app/app/src/main/res/layout/activity_usersettings.xml @@ -158,6 +158,7 @@ android:layout_height="wrap_content" android:layout_weight="5" android:ems="10" + android:focusable="false" android:inputType="date" /> @@ -217,6 +218,7 @@ android:layout_height="wrap_content" android:layout_weight="5" android:ems="10" + android:focusable="false" android:inputType="date" />