Android java datetime values from String to Long to String issue - java

Long time reader, first time poster.
In Android, capturing date from datepicker and storing as string in sqlite. Sorting by date doesn't work because they're strings (unless I'm doing it wrong.
I've googled this issue for ~5 days, and it looks like there should be a way to capture the date from the date picker, convert it to a Long, store it in sqlite as a Long, select and sort on the Long date value, then convert the Long back to a "mm/dd/yyyy" string for display. I've tried various combinations of parse statements, Date, FormatDate, etc. with no luck at all.
My actual application flow would be:
On activity start, get today's date and display it in button which calls the datepicker.
Capture new date from datepicker (if one is entered), save it as a long to sqlite.
On opening an activity showing a listview of records, select from sqlite with orderby on date (Long), convert Long to "mm/dd/yyyy" string for display in ListView.
If someone could point me at a code sample, it would be greatly appreciated - thanks!
Evan

Hours of hair-pulling later, the solution is sort of a mix of the answers given, and some other things:
// variables declared
private int mYear;
private int mMonth;
private int mDay;
// datepicker declared and listened for
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateDisplay();
}
};
// converting the datestring from the picker to a long:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, mDay);
c.set(Calendar.MONTH, mMonth);
c.set(Calendar.YEAR, mYear);
Long lDate = c.getTime().getTime();
//The formatting that worked on the trip back from long to string
// (I spent hours with SimpleDateFormat strings, years that were off by 1500, etc.):
String DateFormatted = DateFormat.getDateFormat(getApplicationContext()).format(helper.getDate(c)); // helper.getDate(c) is just the passing back of the Long date from my SELECT statement
New to the forum - I tried to vote up as useful, but I don't have enough reputation points yet.

All Date objects in java are just Long values behind the scenes. You can get the Long value from a java Date object using getTime(), storing the resulting long value, and then initializing a new Date object using that long value in the constructor. Since the DatePicker gives interfaces to Day, Month and Year you should use the java Calendar class as an interim by creating a new Calendar object, setting the day, month and year before extracting a Date object and then a long value from the Date object.
I would say something along these lines:
DatePicker dp = blah blah;
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, dp.getDayOfMonth());
c.set(Calendar.MONTH, dp.getMonth());;
c.set(Calendar.YEAR, dp.getYear());
long l = c.getTime().getTime();
From here you can serialize your long value. Obviously then to reverse the process you pull the long value out, construct a Date object with the long value and then use a Calendar.setTime(Date) call before using the Calendar.get function to get the values to use on the DatePicker.init function, or utilizing a SimpleDateFormat object to get it prepped for display in a format like you described.

I'd just use a date as I think Calendar objects are a bit heavy for this task. Get your values from your DatePicker :
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateDisplay();
}
Use the integers provide to the DatePicker to create a Date:
Date date = new Date(mYear, mMonth, mDay);
Then store and sort by the long value : date.getTime().
Alternatively, if you really must use strings for sorting dates, format them in yyyy/mm/dd format to ensure proper sorting, even then you need to watch out. I've just done some tests with SimpleDateFormat and it parses inappropriate date strings e.g. 2010/09/31 is interpreted as 2010/10/01.
When checking stuff like this I would always recommend running up some JUnit tests.

Related

Store Datepicker from Android Studio into Firebase (Java)

I have a datepicker on my android studio app. The data has successfully shown as date, but in firebase it became a random number. This is my code
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMMM-YYYY");
Date date_minimal;
Date date_maximal;
DatePickerDialog datePickerDialog = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
calendar.set(year, month, dayOfMonth);
tgl_daftar.setText(simpleDateFormat.format(calendar.getTime()));
tgl_daftar_date = calendar.getTime();
database.child("user").push().setValue(new dataUser(
nama,
radioButton.getText().toString(),
jurusan,
tgl_daftar_date.getTime()
When input the data, the date came out as a date like this.
screenshot of data in app
But in firebase, it became like this.
screenshot of firebase
I want it to display as a date too in firebase. How do i fix this? Thank you
You're call tgl_daftar_date.getTime() to store the Date object. This method is documented as:
returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
So the number that is stored is the number of milliseconds since January 1, 1970, often also referred to as the epoch. This is a very common format to store timestamps in, especially in databases that (like Firebase's Realtime Database) cannot store Java's Date objects natively.
If you store a Date/timestamp right now, the value will be:
console.log(Date.now())
To convert the value from the database back to a Java Date object, see How to convert currentTimeMillis to a date in Java?

Parse Date String Return Wrong Month

I try to parse date string but always get wrong month. Here's my code.
This is code to select date from calender
#OnClick(R.id.tedit_tgllahir_addnew) void showTimeDialog(){
calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
date = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(AddDataForNewUserActivity.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
etTgl.setText(String.format("%02d/%02d/%02d", year, month+1, dayOfMonth));
}
}, year, month, date);
datePickerDialog.show();
}
and this is when i want to parse data
birth = LocalDate.of(list.getTglLahirAnak().getYear() + 1900, list.getTglLahirAnak().getMonth(), list.getTglLahirAnak().getDate());
int year = Period.between(birth, LocalDate.now()).getYears();
int month = Period.between(birth, LocalDate.now()).getMonths();
int totalBulan = year * 12 + month;
Whenever I input date from the calender, it always shows the wrong month. For example I choose May but in the system read April. Thanks to all who are willing to help.
I gather from your question that you are using the backport of JSR-310, probably the Android edition, ThreeTenABP. If so, go all-in on that and drop the use of the poorly designed and long outdated Calendar and Date classes.
Even if the use of the Date class is dictated from outside of your control, you must still stay away from its deprecated methods including getYear(), getMonth() and getDate(). You are trying the good thing when receiving a Date and converting it to a LocalDate first thing. Use DateTimeUtils from the backport for a first conversion.
But let’s take it from the top. Use LocalDate for setting the initial date of your date picker. Don’t use the old-fashioned Calendar class. I have not compiled the code, so please forgive if there’s a typo.
LocalDate today = LocalDate.now(ZoneId.systemDefault());
year = today.getYear();
month = today.getMonthValue(); // naturally 1-based
date = today.getDayOfMonth();
DatePickerDialog datePickerDialog = new DatePickerDialog(AddDataForNewUserActivity.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
// will return to this part later
}
}, year, month - 1, date); // Pass 0-based month
When the user selects a date from the calendar/date picker, don’t store it as a string. Store it as a LocalDate object. This saves you from doing any parsing later, and your code also shows that you need a LocalDate. Obviously if you want to show the selected date to the user, format the date into a string for that purpose (only). Use a DateTimeFormatter for formatting:
private static final DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("yy/MM/dd");
Now we go:
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
// Store the selected date somewhere you can find it later
selectedLocalDate = LocalDate.of(year, month + 1, dayOfMonth);
// Display to the user
String formattedDate = selectedLocalDate.format(dateFormatter);
etTgl.setText(formattedDate);
}
Now the calculation of age in months poses no problem anymore:
birth = selectedLocalDate;
long totalBulan = Period.between(birth, LocalDate.now(ZoneId.systemDefault()))
.toTotalMonths();
If you cannot control what you get from list.getTglLahirAnak(), the conversion from Date to LocalDate is:
Date oldfashionedDate = list.getTglLahirAnak();
birth = DateTimeUtils.toInstant(oldfashionedDate)
.atZone(ZoneId.systemDefault())
.toLocalDate();
Now the calculation of age proceeds as before.
What went wrong in your code?
Just like the outdated Calendar also the deprecated Date.getMonth() numbers the months from 0 for January through 11 for December. So if you pick a date in May, list.getTglLahirAnak().getMonth() returns 4 for May. When you feed this into a LocalDate with its natural and sensible month numbering, it gives you April.

Java: How can I create method that works on my date class

I have a date class and it has the following
public class Date {
public int month;
public int day;
public int year;
public Date(int m, int d, int y)
{
month = m;
day = d;
year = y;
}
public Date increase(int numberOfDays)
{
day += numberOfDays;
return this;
}
My question is what is the easiest way to do increasing of number of days to that given instance of Date? Like for example I have a created an instance of new Date(4,20,2016).increase(30); which would increase the given date addition 30 days. That would be sometime in May 19 I think. The method above should work if it's less than the max day of the month. But I haven't figure out how to do the calculation including the month and year. Like I added 365 days to that date would be 4/20/2017. Just an idea would be helpful. Thanks
use Java Calendar object instead. https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, 30); // add 30 days
date = cal.getTime();
using jcalendar you can add the dates try this example
Implementing this yourself is a suprisingly tricky task. More so since you are storing your Date as a separate month, year and day. You would have to store information about the number of days in every month, along with information about leap years. In short, trying to re-implement Date is not easy.
One solution to storing a "day, month, year" date before Java 8 came along was to use Joda. Using Joda's LocalDate class, you can do:
LocalDate date = LocalDate.now();
date = date.plusDays(30);
This functionality is now available in Java 8's java.time package, using the same LocalDate class name. Take a look at the source code for either package to see how it's implemented.
In short, LocalDate.plusDays() first converts the "month, day, year" date to a single number of days since the "epoch", using an algorithm that's around twenty lines long. Then, it adds the requested number of days to that number. Finally, it converts that number back to a "day, month, year" using another algorithm that's even longer.

get yesterday date from timestamp [duplicate]

This question already has answers here:
Get yesterday's date using Date [duplicate]
(8 answers)
Closed 8 years ago.
I've got an object with a field timestamp with type java.sql.Timestamp;.
And I need to get objects with yesterday date from a collection.
How to get them?
I mean I need something like this
for(int i = 0; i < items.size(); i++) {
(if the items.get(i).date == yesterday_date)
(get object)
}
You can get yesterday's Date by following approach Answered by Jiger Joshi.
And by using new Timestamp(java.util.Date) you can get yesterday's timestamp, you should use Timestamp#equals to equaling two different timestamp.
if (items.get(i).date.equals(getYesterdaytimestamp())){
...
}
And there are something which you must consider while implementing this. Calender#getTime which returns Date object and date object contains date with time, so in that case your equaling date or timestamp must be exactly equals with yesterday's date and time.
If requirement is, it needs to equal just yesterday no not where time is not considerable fact. In that case you need to equals two timestamp after discarding time part.
if (equalsWithYesterday(items.get(i).date)){
...
}
...
public boolean equalsWithYesterday(Timestamp st){
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); // Time part has discarded
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
Date yesterday = dateFormat.parse(dateFormat.format(cal.getTime())); // get yesterday's Date without time part
Date srcDate = new Date(st);
Date srcDateWithoutTime =dateFormat.parse(dateFormat.format(srcDate));
return yesterday.equals(srcDateWithoutTime ); // checks src date equals yesterday.
}
You can convert the timestamp object to date object like this:
Date date = new Date(items.get(i).getTime());
or you can simply use method Timestamp#compareTo(Date o)
items.get(i).compareTo(yesterday_date);
I hope you are not interested to compare the time?
Simply use Calendar class to extract the day, month, year etc. from the date and simply compare it.
Use Calendar#get() method to get the specific field from the date object.
How to subtract one day from the current date?
// get Calendar with current date
Calendar cal = Calendar.getInstance();
// get yesterday's date
cal.add(Calendar.DATE, -1);
// get components of yesterday's date
int month = cal.get(Calendar.MONTH) + 1; // 0 for January, 1 for Feb and so on
int day = cal.get(Calendar.DATE);
int year = cal.get(Calendar.YEAR);
// get yesterday's date in milliseconds
long lMillis = cal.getTime().getTime();

Statically created dates are not equal?

I'm testing the equality of dates that I create using constants and for some reason the tests are all failing.
public static Date date(int year, int month, int date, int hour, int minute) {
Calendar working = GregorianCalendar.getInstance();
working.set(year, month, date, hour, minute, 1);
return working.getTime();
}
If I create that with the same year, month, date, hour etc then I expect it to be equal. Except that it inconsistantly isn't. I use this function in two different classes and the objects aren't equal - except only sometimes.
What's the issue? The epoch it gives me is occasionally 1 second behind the other and I'm not entirely sure why.
getTime is millisecond precision, you are only setting to second precision. So when you compare the Dates using the .equals() method it will return false.
Stop using the abomination of the java date time api and use jodatime instead.
DateTime dateTime = new DateTime().secOfDay().roundFloorCopy();
dateTime.equals(myOtherDateTimeCreatedSameway);
Or if you are just worried about date, not time, use LocalDate.
The old calendar-API is undoubtedly horrible in general but I show a possible solution which suppresses the millisecond part generated in constructor. This will work as long as you don't change the timezone. So sometimes the Calendar-API is underestimated while JodaTime is often overestimated.
public static Date date(int year, int month, int date, int hour, int minute) {
// current time in system timezone
GregorianCalendar working = new GregorianCalendar();
// assuming you rather want second set to zero
working.set(year, month, date, hour, minute, 0);
// no millisecond part
working.set(Calendar.MILLISECOND, 0);
return working.getTime();
}

Categories