Android: Incorrect Date when Converting from Seconds - java

I'm parsing some date data from an XML string into a hierarchy of model objects. The dates are in a 10-digit seconds format. I use the method below to convert those seconds into Date objects
public static Date getDateFromSecondsString(String seconds){
try{
long millis = Long.parseLong(seconds) * 1000;
Date date = new Date(millis);
return date;
}
catch(Exception ex){
ex.printStackTrace();
}
return null;
}
Here's the problem...
When I step through the parsing code at run-time (the code snippet for that is shown below), the date conversion method is returning the expected date.
Element startDateElt = eventElt.getChild("start_date");
if(startDateElt != null){
startDateElt.setEndTextElementListener(new EndTextElementListener() {
#Override
public void end(String body) {
currEvent.startDate = DateTimeUtil.getDateFromSecondsString(body);
}
});
}
However, once I have finished populating my model objects with the parsed data, the dates are wrong. Here are some examples:
Seconds: 1369206000, should be: 2013-05-22, unfortunately is: 2013-05-03
Seconds: 1369292400, should be: 2013-05-23, unfortunately is: 2013-05-04
Seconds: 1369551600, should be: 2013-05-26, unfortunately is: 2013-04-30
Seconds: 1369638000, should be: 2013-05-27, unfortunately is: 2013-05-01
Seconds: 1369724400, should be: 2013-05-28, unfortunately is: 2013-05-02
I have looked through my code to make sure nothing is modifying the dates between the time that the XML is parsed and the time that I display the dates. I know that the Date objects in Java/Android are a little messed up, but would they behave like this?
Any suggestions or insights would be greatly appreciated.

Turns out, the problem was that I was using Date.toDay() in some places where I should have been using Date.toDate() instead. Grrr! I dislike Java's Date implementation.
Thanks to all of you that gave your two cents, and let this be a warning for anyone who may be confusing toDay() with toDate().

Related

Output for finding the time in 24 hour input given in 12hour format(without using any inbuild class)

I am trying to convert the time given in 12hr format to 24 hour format.
But I am not getting expected output when the time is in AM.
Can Anyone guide me why?
Input form
HH:MM:SS
MyApproach
To convert the time in 24 hr format I checked if the time is given in AM,
I printed the output as it is.
If the time is given in PM,I added 12 Hours to the time
Below is my function:
public static String timeConversion(String time)
{
String strnew1="";
String strnew2="";
String strnew="";
String strnew3="";
boolean b1=true;
for(int i=time.length()-2;i<time.length();i++)
{
strnew=strnew+time.charAt(i);
}
if(strnew=="AM")
{
b1=false;
for(int m=0;m<time.length()-2;m++)
{
strnew3=strnew3+time.charAt(m);
}
System.out.println("jhh");
System.out.println(strnew3);
}
else
{
for(int j=0;j<2;j++)
{
strnew1=strnew1+time.charAt(j);
}
int a=Integer.parseInt(strnew1);
int b=a+12;
strnew2=b+strnew2;
for(int k=2;k<time.length()-2;k++)
{
strnew2=strnew2+time.charAt(k);
}
}
if(b1==false)
return strnew3;
else
return strnew2;
}
}
**OutputShown**
Input OutputShown Expected Output
05:32:32AM 17:32:32 05:32:32
The problem is here
if(strnew=="AM")
Strings in Java are compared like this:
if(strnew.equals("AM"))
But there is also another problem 12PM should become 12 and 12AM should become 00. You need to check for these special cases.

Time difference calculation issues

I have a table called by name Symbols in my Application which will be updated continously for every 8 minutes
Each record inside the Symbol table has got a attribute by name updated-at and whose value is in timestamp as shown
"updated_at" : NumberLong("1375715967249")
I have a task to show the updated data to the users from the symbols table
In case the symbol is not updated for 9 minutes , i need to executed a particular task and if updated a different task
I was following this logic , please let me know if this has got any loop holes ?? ( I mean like day like settings --- or any such )
package com;
public class UnixTimeConversion {
public static void main(String args[]) {
long timeStamp = 1375715967249l;
java.util.Date date = new java.util.Date();
long currtime = date.getTime();
if ((currtime - timeStamp) > 600000) {
System.out.println("Greater than 10 minutes since executed");
} else {
System.out.println("Lesser than 10 minutes since executed");
}
}
}
Better to try in this way
long timeStamp = 1375715967249l;
long currTime = System.currentTimeMillis();
if ((currTime - timeStamp) > 10*60*1000) {
System.out.println("Greater than 10 minutes since executed");
} else {
System.out.println("Lesser than 10 minutes since executed");
}
10min = 10*60*1000 ms
UNIX timestamps don't care about Timezones, UTC leap seconds or anything. It's just a number linearly measuring the passing of time. If you don't care about wallclock time either, there's no problem. You just have to take care that you convert your source material to UNIX timestamps in the right manner.

Time Update Application

I am trying to make a digital clock in android.
I looked into the Time and Date classes.
However I cannot find any API that is tells me how to obtain when a minute has passed?
For e.g. when working with locationManagers,
public void onLocationChanged(Location location)
is called when new location is available.
Similarly I am looking for something that is called when time changes, where time is in format hh:mm or hh:mm:ss.
You'll need joda for this code, but you should be using it anyway for anything involving time calculations in Java.
public DateTime date = new DateTime();
public void updateClock {
if (Seconds.secondsBetween(new DateTime(), date).getValue() != 1) {
return;
}
date = new DateTime();
// do your thing
}

Sorting out the dates in chronological order

Friends I am having a String that contains date-record
String date=10-Oct-2012 #12-Oct-2012 #$12-Oct-2012 #12-Oct-2012 #$12-Sept-2012 13:50#12-Oct-2012 13:50#$12-Feb-2012 13:50#12-Oct-2012 13:50#$
List<Date> myList=new ArrayList<Date>() ;
I need to compare the dates 10-Oct-2012,12-OCt-2012,12-Sept-2012,12-Feb-2012 ie every odd date such that I can arrange them in a chronological order.I am confused on this implementation, please provide me with guidance/hint to solve the problem.
In this case the solution after chronological order would be 12-Feb-2012 #12-Oct-2012 #12-Sept-2012 #12-Oct-2012 #$10-Oct-2012 #12-Oct-2012 #$12-Oct-2012 #12-Oct-2012
Friends,to solve the problem I have created a Hashmap where I am planning to save the first date as key and the entire String as value.
String[] tokens=date.split("\\$");
demo[0]=demo[0].replaceAll("-", ".");
if(tokens.length>0)
{
for(int iTmp=tokens.length-1;iTmp>=0;iTmp--)
{
String []demo = tokens[iTmp].split("\\#");
demo[0] = demo[0].replace("Jan", "1")
.replace("Feb", "2").replace("March","3").replace("April","4").replace("May","5").replace("Jun","6").replace("July","7").replace("Aug","8")
.replace("Sept","9").replace("Oct","10").replace("Nov","11").replace("Dec","12");
demo[0]=demo[0]+" 00:05:00";
Date date1 = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yy");
try {
date1 = (Date)formatter.parse(demo[0]);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myList.add(date1);
System.out.println("ADDED DATE IS"+date1);
//System.out.println("KEY VALUE PAIRS "+key+" "+tokens[iTmp]);
}
}
System.out.println("READING LISTs");
for(int iTmp=0;iTmp<myList.size();iTmp++)
{
System.out.println(myList.get(iTmp));
}
Collections.sort(myList);
System.out.println("After Sorting");
for(int iTmp=0;iTmp<myList.size();iTmp++)
{
System.out.println(myList.get(iTmp));
System.out.println();
}
It sounds pretty simple to me:
Parse each value into a more suitable type (Calendar, Date, Joda Time's LocalDate)
Sort in natural order
(Using Joda Time is the preferred option here IMO, as neither Calendar nor Date really represent "just a date"; you'd have to put all values into the same time zone etc.)
I would definitely not recommend trying to compare them as strings. As usual, convert your data into the most appropriate type for the information it's trying to represent as early as possible - and convert it into serializing representations (e.g. for storage, propagation to a web service etc) as late as possible.
Split the string and then
You can use gregorian calender (built in)
or you can use the yoda-time library
i can't say more about the sorting though
If you are developing for Android (there is an Android tag on your question), then you should know about the Time structures and methods in the Android SDK.
If possible, try to use a string representation of your date/time stamp that itself can be sorted naturally, like the RFC 3339 format (which Android supports with built-in methods). This will let you work more easily with string timestamps, and also give you a simple way to convert to a canonical or integer-type format if desired.

Grouping objects by date: am I an idiot?

I have a list of objects called Activity:
class Activity {
public Date activityDate;
public double amount;
}
I want to iterate through List, group them by date and return a new list . Here's what I currently do:
private List<Activity> groupToList(List<Activity> activityList) {
SimpleDateFormatter sdf = new SimpleDateFormatter("YYYY-MM-DD");
Map<String,Activity> groupMap = new HashMap<String,Activity>();
for (Activity a in activityList) {
String key = sdf.format(a.getActivityDate());
Activity group = groupMap.get(key);
if (group == null) {
group = new Activity();
groupMap.add(key, group);
}
group.setAmount(group.getAmount() + a.getAmount());
}
return new ArrayList<Activity>(groupMap.values());
}
Is it a WTF to use the DateFormatter in this way?
I'm using the DateFormatter because each activityDate could have time information.
I would just use the date object itself as the key. If it it bothers you because the date object is mutable, then use its toString() value. No reason to go making formats.
If the issue is that you want to normalize the date by removing the time component, it would be much better to do that withing the Activity object and remove the time component. If the issue is still further that there are potential time zone issues, I would use JodaTime, but there is no object in the JDK currently that represents a pure date without time, so going with a string isn't outrageous, but it should be hidden behind a method in the Activity object and the fact that it is a date formatted string without a time component should be an implementation detail.
java.util.Date is a quite poor abstraction for your need; it is IMO fair to stick to strings if nothing better is around, HOWEVER Joda-time provides a good datatype for you: DateMidnight or alternatively LocalDate if Activity is strictly timezome-independant.
other than that, the code looks good to me, you might be able to shorten it a bit using an implementation of Multimap, to avoid messy null-checking code. to be honest, it doesn't get much shorter than your solution:
public List<Activity> groupedByDate(List<Activity> input) {
//group by day
final Multimap<DateMidnight, Activity> activityByDay
= Multimaps.index(input, new Function<Activity, DateMidnight>() {
#Override
public DateMidnight apply(Activity from) {
return new DateMidnight(from.activityDate);
}
});
//for each day, sum up amount
List<Activity> ret = Lists.newArrayList();
for (DateMidnight day : activityByDay.keySet()) {
Activity ins = new Activity();
ins.activityDate = day.toDate();
for (Activity activity : activityByDay.get(day)) {
ins.amount+=activity.amount;
}
}
return ret;
}
Why not simply create a HashMap<Date, Activity>() instead of the roundabout way with Strings?
Sorry, I didn't answer the question. The answer is: yes, unless I am an idiot ;)
You could do this using the Date as the key if you used a TreeMap and provided a Comparator that only compared the year, month and day and not the time.
As already mentioned the best solution is to represent your date with day precission. If this is not possible joda is nice library.
If you can ignore daylight saving time then grouping by date can be accomplished much easier. A unix time day is 86 400 s long. The timestamp does ignore leap seconds. (Your timer stops for one second or the leap second is distributed in some way.) All date values were day is equal are the same day:
int msPerDay = 86400 * 1000;
long day = new Date().getTime() / msPerDay
One minor point is to adjust the timezone. For my timezone CET (UTC/GMT +1 hour) the GMT day starts one our later:
new GregorianCalendar(2009, 10, 1, 1, 0).getTime().getTime() / msPerDay) ==
new GregorianCalendar(2009, 10, 2, 0, 59).getTime().getTime() / msPerDay) ==
new Date().getTime() / msPerDay
If the daylight saving time is significant the best way is to use joda. The rules are just to complicated and locale specific to implement.

Categories

Resources