I've to 2 different epoch timestamp A and B. For each day i have different sunrise and sunset times.
Suppose for day 1, which is timestamp A day sunrise time is 6.00 am and sun set time as 6.30 pm and for day2, sunrise time is 6.05 am and sunset time is 6.25pm, etc., below is the format i have,
val sunRise = mapOf<Int,String>(1 to "6.00", 2 to "6.05",3 to "6.01", 4 to "6.06")
val sunSet = mapOf<Int,String>(1 to "18.30", 2 to "18.25",3 to "18.20", 4 to "18.23")
val startTime = 1579919400000
val endTime = 1580203800000
Now how to calculate time taken between these to timestamps which are only between sunRise and sunSet in Android
Try Below method will calculate difference between two times.
System.out.println("==result==: " + stringForTime(endTime - startTime));
public String stringForTime(long timeMs) {
long totalSeconds = timeMs / 1000;
long seconds = totalSeconds % 60;
long minutes = (totalSeconds / 60) % 60;
long hours = totalSeconds / 3600;
Formatter mFormatter = new Formatter();
if (hours > 0) {
return mFormatter.format("%02d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
In my app user pick a date and time from a date and time picker (from the past dates) then I want to start a count up timer from that date and I need to run it in a service so that if my app killed, timer wouldn't stop.
I've tried Chronometer and some similar solution on stackOverFlow but didnt get any correct solution.
Please check below picture, that It is so similar to what I need:
https://ibb.co/rFz24kg
For getting the difference in the dates (here, date2 can be the user-picked date and date1 can be current datetime (which you can get by calling : new Date())):
public static String getDifferenceBetweenDates(Date date1, Date date2) {
long secondsInMilli = 1000;
long minutesInMilli = secondsInMilli * 60;
long hoursInMilli = minutesInMilli * 60;
long daysInMilli = hoursInMilli * 24;
long difference = date2.getTime() - date1.getTime();
long elapsedDays = difference / daysInMilli;
difference = difference % daysInMilli;
long elapsedHours = difference / hoursInMilli;
difference = difference % hoursInMilli;
long elapsedMinutes = difference / minutesInMilli;
difference = difference % minutesInMilli;
long elapsedSeconds = difference / secondsInMilli;
return String.format("%s days %s hours %s minutes %s seconds", elapsedDays, elapsedHours, elapsedMinutes, elapsedSeconds);
}
Now once you get the difference, you can use this as a Count Up Timer and define onTick() to update your view every mCountUpInterval time interval (defined in the CountUpTimer class)
I want my app to show the time elapsed from the point an entry was stored in the database to the point it is fetched from the database.
I am currently doing something like this which gives me time elapsed in seconds:
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss aa");
Date systemDate = Calendar.getInstance().getTime();
String myDate = sdf.format(systemDate);
Date Date1 = sdf.parse(myDate);
Date Date2 = sdf.parse(savedDate);
int dateDiff = getTimeRemaining();
long millse = Date1.getTime() - Date2.getTime();
long mills = Math.abs(millse);
long Mins = mills/(1000*60);
String diff = +dateDiff+ "days " + Mins+ " mins";
cal[1] = "" +Mins;
t3.setText(diff);
But I also want it to include the no of days since the data was stored. As of now, it resets when the day is over. I want it to give me the total minutes after N days. How should I do it? Thanks in advance.
You firstly need to determine the number of seconds from database-stored-time until now.
long ageOfDatabaseEntry = (System.currentTimeMillis() - databaseEnteredTimeMillis)
You then need to determine how many days you want, then modulo the age by that number to get the remaining number of milliseconds.
long getRemainingMinutes(long age, int days) {
// Use the modulus operator to get the remainder of the age and days
long remainder = age % (days * 86400000);
if(remainder == age) {
throw new InvalidArgumentException("The number of days required exceeds the age of the database entry. Handle this properly.");
}
// Turn the remainder in milliseconds into minutes and return it
return remainder / 60000;
}
I am using a Date and Time Dialog to get a Date and Time for an Event Specifed by the User. That data is the Converted by doing the following:
int yearE = Integer.valueOf(evntDate.split("/")[2]);
int monthE = Integer.valueOf(evntDate.split("/")[1]);
int dayE = Integer.valueOf(evntDate.split("/")[0]);
int hour = Integer.valueOf(evntTm.split(":")[0]);
int min = Integer.valueOf(evntTm.split(":")[1]);
With the Values of:
eventDate = "3/5/2015";
eventTime = "13:2";
I then get that data and COnvert it into Milliseconds and Store that in the Database:
newCalendar.set(yearE, monthE, dayE,hour, min, 0);
startTime = newCalendar.getTimeInMillis();
...
When I load the Info from the Database, I try to calculate the amount of time left until the Specified date. So I do the following:
Long timeL = Long.valueOf(time);
Calendar eventDay = Calendar.getInstance();
eventDay.setTimeInMillis(timeL);
Calendar today = Calendar.getInstance();
long diff = eventDay.getTimeInMillis() - today.getTimeInMillis();
// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
...
When I log the above data, the days are usually around 30-32 and the rest of the data is incorrect as well. What am I doing wrong? Or what are some alternatives?
Consider using the Joda time library instead of Calendar, it's much easier to work with.
As you're on android, I'll assume that you're using gradle, so go ahead and drop this in your dependencies
compile 'joda-time:joda-time:2.3'
I've created a small psvm to demo how you can use it
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.PeriodFormat;
import static java.lang.String.format;
public class DateTimeDemo {
public static void main(String[] args) {
// Your date/time values, I'll assume you missed a digit off the time ;)
String eventDate = "3/5/2015";
String eventTime = "13:20";
// convert these to a DateTime object
DateTime targetDateTime = DateTime.parse(format("%s %s", eventDate, eventTime), DateTimeFormat.forPattern("dd/MM/yyyy HH:mm"));
// print out the millis, or in your case, save it to DB
System.out.println("targetDateTime in millis is " + targetDateTime.getMillis());
// grab a timestamp
DateTime now = DateTime.now();
// print it out, just for demo
System.out.println("millis for now is " + now.getMillis());
// create a period object between the two
Period period = new Period(now, targetDateTime);
// print out each part
System.out.println("seconds " + period.getSeconds());
System.out.println("hours " + period.getHours());
System.out.println("months " + period.getMonths());
// convert the period to a printable String
String prettyPeriod = PeriodFormat.getDefault().print(period);
// write it out!
System.out.println(prettyPeriod);
}
}
Output is
targetDateTime in millis is 1430623200000
millis for now is 1425527593584
seconds 46
hours 22
months 1
1 month, 3 weeks, 6 days, 22 hours, 26 minutes, 46 seconds and 416 milliseconds
You can use Joda for that.
long dbTime = 1425525415837L;
Period period = new Period( dbTime, System.currentTimeMillis() );
String formatted = PeriodFormat.getDefault().print(period);
System.out.println( formatted );
If you want more control of the format use PeriodFormatter.
If you want to get the seconds, minutes, hours, etc. and not just print them, you can use the various available methods. For example:
period.getSeconds();
period.getHours();
period.getMonths();
More formatting options are described in this question.
Are you expecting to see something similar:
seconds = 36 (always less than 60)
minutes = 12 (always less that 60)
hours = 17 (always less than 24)
days = 45 (always less that 31 if # of months is used, else < 366 if # of years is used)
...
...
from:
// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
Its a logical error then. TimeUnit.MILLISECONDS.toXXXX(long) converts the whole time-difference into the specified units. This is of no value to you.
As an example, say you set the event's date to 32 days from now - and time to 13:15.
Millisecond difference =
2764800000 (32 days in millis)
+ 46800000 (13 hours in millis)
+ 900000 (15 minutes in millis)
= 2812500000
Using this time-difference, the following log:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
produces:
Seconds left: 2812500
Minutes left: 46875
Hours left: 781
Days left: 32
These figures are not off. A quick check would be: time difference in millis was: 2812500000 => in seconds would be diff/1000 = 2812500 => in minutes would be => diff/1000/60 = 46875 and so on.
Relative time:
To get relative time such as 32 days, 13 hours and 15 minutes left, you will have to do the heavy-lifting yourself. As an example:
// I will use the actual values instead of defined
// variables to make this easier to follow
long timeDiff = 2812500000L;
// Simple division // we don't care about the remainder
// Result: 32
int days = 2812500000 / DateUtils.DAY_IN_MILLIS;
// This is what's left over after we take the days out.
// We'll use this to get the number of hours.
// Result: 47700000
long remainderFromDays = 2812500000 % DateUtils.DAY_IN_MILLIS;
// Simple division // we don't care about the remainder
// Result: 13
int hours = 47700000 / DateUtils.HOUR_IN_MILLIS;
// This is what's left over after we take the hours out.
// We'll use this to get the number of minutes.
// Result: 900000
long remainderFromHours = 47700000 % DateUtils.HOUR_IN_MILLIS;
// Result: 15
int minutes = 900000 / DateUtils.MINUTE_IN_MILLIS;
// Result: 0
long remainderFromMinutes = 900000 % DateUtils.MINUTE_IN_MILLIS;
// Result: 0
int seconds = 0 / 1000; // 1000 ms = 1 sec
Log.i("Time-Difference", "Event in: " + String.format("Event in %d days, %d hours, %d minutes and %d seconds", days, hours, minutes, seconds));
Output:
Event in: 32 days, 13 hours, 15 minutes and 0 seconds
This is the very reason everyone here is suggesting Joda Time. The computation above is just off the top of my head. I cannot guarantee its correctness. If you also need relative month difference (such as 3 months, 2 days ....), a lot of work will be required. There isn't a DateUtils.MONTH_IN_MILLIS constant - varying number of days - 28, 29, 30, 31.
On the other hand, Joda Time is a tried & tested product. But, if all you need is one kind of computation, used scarcely (if ever), I'd say spend some time and come up with your own implementation rather than under-employ Joda Time.
Your code looks fine to me for what you are doing. Using org.joda.time as others have suggested is a best-practice, but it won't fix the problem. Instead you need to do two things:
Verify the Month that the user entered is in range (they may have entered the date in MM/DD/YYYY format). Month values greater than 12 won't throw an exception and your diff will be way off.
The line where you construct your date, subtract 1 from the month since months should be from 0 to 11, like:
newCalendar.set(yearE, monthE-1, dayE,hour, min, 0);
Hi every one i want to devolepe an Alarm App i get the sunrise and sunset time from webservice now i need to manipulate these timing my date store in string when i calculate difference it give correct result when i add two time values it cause problem like
i try it like below to get the manipulated time that i applied manipulation but
it give wrong result
SimpleDateFormat sdf = new SimpleDateFormat("kk:mm:ss");
Date Date1 = sdf.parse(sunrsetat);
Date Date2 = sdf.parse("00:12:00");
long millse = Date1.getTime() + Date2.getTime();
long mills = Math.abs(millse);
int Hours = (int) (mills/(60*60*1000));<------ here it give hour 09 and it must be 19
int Mins = (int) (mills/(1000*60)) % 60;
long Secs = (int) (mills / 1000) % 60;
String time = String.format("%02d:%02d:%02d", Hours, Mins, Secs);
hanfiaiftaritime.setText(time);
Error occurs because Date.getTime() returns millis since Jan 1, 1970, so your mills field has value (assuming date1 < date2) of 2*date1 + difference-in-millis-date2-date1. (http://developer.android.com/reference/java/util/Date.html#getTime())
Solution: use Calendar class.
Calendar calendar = Calendar.getInstance();
calendar.setTime(date1);
calendar.add(Calendar.SECOND, (int) date2.getTime() / 1000);
long millse = calendar.getTimeInMillis();
In this case computing hours/mins/seconds becomes redundant cause you can use http://developer.android.com/reference/java/util/Calendar.html#get(int) like this:
int hours = calendar.get(Calendar.HOUR_OF_DAY);