Android issue displaying day of week string - android

I have seen many examples of working with dates in Android using Calendar and GregorianCalendar classes.
Recently I came across the following in Android Developers Time documentation:
The Time class is a faster replacement for the java.util.Calendar and java.util.GregorianCalendar classes. An instance of the Time class represents a moment in time, specified with second precision.
This prompted me to replace all the Calendar functions with the faster Time class functions.
Here is my code for reading the date stored in the SQLite database:
// extract milliseconds (long) value from SQLite database
Long timeLong = note.getLong(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_DATE));
Time currentTime.set(timeLong);
Here is the partial code for preparing the integer values for populating the date picker and displaying the formatted date string in the mPickDate button:
mDay = currentTime.monthDay; // Day of the month (0-31)
mMonth = currentTime.month; // Month (0-11)
mYear = currentTime.year; // Year
mPickDate.setText(currentTime.format("%A, %d %b %Y")); // using strftime equivalent to dateFormat = new SimpleDateFormat("E, dd MMM yyyy");
Note the format %A used to get the long string for the day of the week.
This part of the formatting code works perfectly well and displays the correct string with the formatted date, including the correct day of the week.
Clicking on the mPickDate button invokes the DatePicker widget, which allows for changing and setting the new date.
The following code shows the handling of the newly selected date from the DatePicker:
private DatePickerDialog.OnDateSetListener mDateSetListener =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// new method using Time class
currentTime.set(dayOfMonth, monthOfYear, year);
mPickDate.setText(currentTime.format("%A, %d %b %Y"));
// old method using GregorianCalendar class
//mCalendar = new GregorianCalendar(year, monthOfYear, dayOfMonth);
//mPickDate.setText(dateFormat.format(mCalendar.getTime()));
}
};
The mPickDate button gets the correct date string displayed, as selected in the Date Picker, except for the day of the week (%A), which is always shown as Sunday. Why ?
Note that mPickDate.SetText code is identical to the one used earlier to format the button date string, extracted from the SQLite database field.
I had to modify the above code, by adding an extra line of code to set the date value in the currentTime Time object once again:
currentTime.set(dayOfMonth, monthOfYear, year);
currentTime.set(currentTime.toMillis(true));
mPickDate.setText(currentTime.format("%A, %d %b %Y"));
My question is: why it was necessary to use the currentTime.set procedure twice in the above DatePickerDialog.OnDateSetListener code, in order to get the day of the week string to display correctly ?
Would this possibly be an issue with Android Timecode itself (using SDK version 16) ?

Related

Best way to store date and time in Sqlite database in Android to perform date operations easily

I want to store date and time that user picks through date picker and time picker on Android. By reading various thread I came to conclusion to store date and time in INTEGER format. So I'm converting them to long values using following function but when I'm converting them back to Date it is giving me wrong Date.
private DatePickerDialog.OnDateSetListener startDatePickerListener = new DatePickerDialog.OnDateSetListener(){
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
String dateText = getTimeString(year,monthOfYear,dayOfMonth);
//Converting Date to long so that can be stored in DB
long date = Utility.getDateLong(year,monthOfYear,dayOfMonth);
taskModel.setStartDate(date);
startDateView.setText(dateText);
}
};
public static long getDateLong(int year, int month, int day){
Calendar cal = new GregorianCalendar(year, month, day);
long timeStamp = (cal.getTimeInMillis()+cal.getTimeZone().getOffset(cal.getTimeInMillis()))/1000;
return timeStamp;
}
To convert long value back to Date I'm using the below function :
public static String getDateFromLongValue(long d){
Date date = new Date(d);
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
String formattedDate = dateFormat.format(date);
return formattedDate;
}
But this is giving me the different date then the entered value. Is there any other way to do this. I basically need to compare dates and to find the time elapsed between two dates?
I suggest a duplicate because while "best way" is theoretically debatable, SQLite offers date functions based on the fact that SQLite doesn't have a time and date type, but does offer date functions based ISO-formatted TEXT timestamp.
One item that is definitely not a matter of opinion though is where you want to do the bulk of operations. You have two choices:
Query for a large amount of data then filter that in your app
Query for a subset of that data
You might will run into timing and memory issues if you don't pre-filter your dataset via the query (i.e. using date and time functions off an ISO-formatted text timestamp) and opt to transform epochs in Java.

Android converting calendar in one TimeZone to local TimeZone

I am using following code to convert timezone (GMT-3) to device local timezone.
int hour=17,minute=0,day=12,month=6,year=2014;
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
cal.set(year, (month-1), day,hour,minute);
cal.setTimeZone(TimeZone.getDefault());
Log.d("Time", cal.get(Calendar.DATE)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.YEAR)+" , "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" "+cal.get(Calendar.AM_PM));
My local timezone is GMT+5:30
Expected result is
Time 13/5/2014, 1:30 0
But I am getting the result
12/5/2014 , 13:30 1
Sorry for you, GregorianCalendar is sometimes the hell. Your problem is following:
If you immediately set the timezone after having set the fields for year, month etc. then this mutable calendar class will only shift the timezone retaining the already set fields containing the local time. Those fields for year, month etc. will NOT be recalculated. This behaviour causes a shift on the global timeline represented by cal.getTime(), too.
In order to force the calendar object to recalculate the fields you need to call a getter. Watch out for following code and especially remove the comment marks to see the effect.
int hour = 17, minute = 0, day = 12, month = 6, year = 2014;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
TimeZone tz1 = TimeZone.getTimeZone("GMT-3");
sdf.setTimeZone(tz1);
Calendar cal = new GregorianCalendar(tz1);
cal.set(year, (month - 1), day, hour, minute);
// System.out.println(sdf.format(cal.getTime()));
// System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
TimeZone tz2 = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz2);
cal.setTimeZone(tz2);
System.out.println(sdf.format(cal.getTime()));
System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
Output with comment-disabled lines:
2014-06-12T17:00+0530
Hour=17
Output with enabled lines after having removed the comment marks:
2014-06-12T17:00-0300
Hour=17
2014-06-13T01:30+0530
Hour=1

Initialize date in android datepicker to a specific date, that is not the current date.

In my app I have a date saved in a remote database that I want the date picker to be set to. I've researched and only found examples of setting the datepicker today's date via Calender java util. Example:
final Calendar c = Calendar.getInstance();
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH);
day = c.get(Calendar.DAY_OF_MONTH);
How can I use the Calendar to display my date from the database and not today's date? Do you have any suggestions or examples I can follow?
Update:
After experimenting with Calendar I tried to use
// set Date
String eventYear =date.substring(0,4);
String eventDay =date.substring(5,7);
String eventMonth =date.substring(8,10);
//convert string to int for because calendar only takes int: set(int,int)
int month = Integer.parseInt(eventMonth);
final Calendar c = Calendar.getInstance();
mMonth=c.get(c.set(Calendar.MONTH, Calendar.month));
// or mMonth=c.get(Calendar.MONTH, Calendar.month);
Generates error that says cannot convert int to void.
How can I use Calendar to set it to a specific date? According to google's developers site I should be able to do this.
http://developer.android.com/reference/java/util/Calendar.html
example:
set(Calendar.MONTH, Calendar.SEPTEMBER)
I'd like the date to be display in the datepicker from the server as a default value.
U can use the updateDate(year, month, day_of_month);
date picker returns integer values of day, month and year. so the parameters must be integer values. and the integer value for the month jan in the date picker is 0.
i needed to put the date extracted from a database into a datepicker. I wrote the following code and it works.
DatePicker DOB;
SQLiteDatabase db;
DOB=(DatePicker)findViewById(R.id.datePicker1);
db = openOrCreateDatabase("BdaySMS", SQLiteDatabase.CREATE_IF_NECESSARY, null);
Cursor cur = db.rawQuery("select * from BdaySMS where ph='"+pn+"';", null);//pn is the phone no.
if(cur.moveToFirst())
{
name.setText(cur.getString(0));
phone.setText(cur.getString(1));
DOB.updateDate(Integer.parseInt(cur.getString(4)),Integer.parseInt(cur.getString(3)),Integer.parseInt(cur.getString(2)));
message.setText(cur.getString(5));
}
Use JodaTime
Here's a simple example of how I set a DatePicker and TimePicker from a DateTime object, which could be the current date or any date from the past or future (the attribute in this case is called inspected_at):
DatePicker dp = (DatePicker) findViewById(R.id.inspected_at_date);
TimePicker tp = (TimePicker) findViewById(R.id.inspected_at_time);
DateTime inspected_at = DateTime.now().minusYears(1); // Typically pulled from DB.
int year = inspected_at.getYear() ;
int month = inspected_at.getMonthOfYear() - 1; // Need to subtract 1 here.
int day = inspected_at.getDayOfMonth();
int hour = inspected_at.getHourOfDay();
int minutes = inspected_at.getMinuteOfHour();
dp.updateDate(year, month, day);
tp.setCurrentHour(hour);
tp.setCurrentMinute(minutes);
Hope that helps.
JP

SimpleDateFormat subclass adds 1900 to the year

I've created a couple of subclasses of SimpleDateFormat to simplify dealing with an Azure feed I'm talking to on Android. One of them is as follows:
public class ISO8601TLDateFormat extends SimpleDateFormat {
private static String mISO8601T = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
public ISO8601TLDateFormat() {
super(mISO8601T);
}
public ISO8601TLDateFormat(Locale inLocale) {
super(mISO8601T, inLocale);
}
}
As you can see the intention is to produce or interpret dates looking like
2012-03-17T00:00:00.000+0100
which is what the Azure service is expecting. However, when I feed in Date objects constructed from a DatePicker thus:
mDate = new Date(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
the output of the ISO8601TLDateFormat is
3912-03-17T00:00:00.000+0100
As you can see, the year is 1900 more than I, or anyone else not from the future, would need. I've scrutinized the Date object on its entire journey to the Azure feed system and it reports its date is 2012, which is what I would have expected. Why is the SimpleDateFormat breaking?
The problem is that the constructors of Date do not receive what you expect. Taken from the java documentation:
public Date(int year,
int month,
int date)
Deprecated. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date) or GregorianCalendar(year + 1900, month, date).
Allocates a Date object and initializes it so that it represents midnight, local time, at the beginning of the day specified by the year, month, and date arguments.
Parameters:
year - the year minus 1900.
month - the month between 0-11.
date - the day of the month between 1-31.
You need to keep in mind that you construct a date with 0, 0, 1 being 1st of January 1900.

Date getMonth() in java from 0-11 messes up searches in database?

Second EDIT:
Looks like my issue might be where the date is set from the date picker dialog:
// the callback received when the user "sets" the date in the dialog
private DatePickerDialog.OnDateSetListener mDateSetListener =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
mYear = year;
mMonth = monthOfYear + 1;
mDay = dayOfMonth;
updateDisplay();
}
}
I am +1 to the month, but never taking that off again when i compare for the database...
EDIT:
Okay I did double checked this (finally got to it). Sure enough the
Date test1 = new Date(cobj.getTime().getTime()); //from the Calendar passed in
So the date retrieved from the database is the right date. The one that comes back from my dialog even though it displays correctly using:
String val = cobjstrong text.get(Calendar.MONTH) + "/" +
cobj.get(Calendar.DAY_OF_MONTH) + "/"+ cobj.get(Calendar.YEAR);
...is actually a month ahead when I look at the object as cobj.getTime().getTime(); (a long for the dates I use). Is there some other method or conversion I am missing?
Should I not be using the .getTime on the Calendar Object just to get a long from that (with a call to getTime again on the Date object?). Sometimes it seems to me that my best bet is to store longs in milliseconds to the database and then just retrieve them and do the Date conversions there?
PRE-EDIT question:
SO I have this Date field in a database, that I can store a date to and read a date from, when I read em... I have to add a +1 to the .getMonth() because date returns that as a number 0-11, instead of 1-12. After dealing with this issue and a few others (like .getMinutes returning an int, so if the time is 5:00 only 5:0 is displayed?)but I finally got the date displaying just great, but I found out when I try to query the database on a date things are off I am guessing by one month. So that means a month of
9/8/2011
(dd/mm/YYYY) format, will not query right when using the following ORMLite query:(Notice the .qe, GreaterThanEqual in ormlite).
public void updateDatePickerButtonUI(Calendar cobj, int widget) {
String val = cobj.get(Calendar.MONTH) + "/"+ cobj.get(Calendar.DAY_OF_MONTH)
+ "/"+ cobj.get(Calendar.YEAR);
btnChooseDateReview.setText(val);
//the following just won't query correctly, its a month off
try {
//sessionDate
QueryBuilder<SessionsData, Integer> sb =
mDB.getSessionsDao().queryBuilder();
sb.where().ge(SessionsData.SESSIONSDATE_ID_NAME, cobj.getTime());
List<SessionsData> sessions = mDB.getSessionsDao().query(sb.prepare());
for (int i = 0; i < sessions.size(); i++) {
try {
mDB.getClientsDao().refresh(sessions.get(i).getClient());
mDB.getPackagesDao().refresh(sessions.get(i).getPackage());
} catch (SQLException e) {
...
}
}
theSessions = new CustomSessionReviewAdapter(mContext,
R.layout.session_review_row, sessions);
theSessions.notifyDataSetChanged();
theList.setAdapter(theSessions);
} catch (SQLException e) {
...
}
}
So I must be handling dates wrong, maybe adding to the month for display purposes is not right? or something... maybe in my query with the Calendar object, I can make that month part 0-11 or something...not sure what avenue to take here.
I'm a little confused #CodeJoy. I don't see any references to +1 in your code. I assume that you are doing a +1 while you are building the val for your button text?
ORMLite stores the Date field as a string via the Sqlite driver (i.e. something like 2011-08-10 18:33:30.316) and I am wondering if the conversion to/from a Calendar object generates a Date that does not match the database exactly. Maybe the milliseconds have been truncated? Are you creating a Calendar from the button date string?
Most likely your problem has nothing to do with the +/- 1 issue around the month. The getTime() method should do that conversion appropriately.
I would debug your app and see what the cobj.getTime() returns for a date and then do a mDB.getSessionsDao().queryForAll() and take a look at how the Date is being returned from the database driver.

Categories

Resources