Getting the timestamp from mysql it returns something like this "2014-03-19 12:00:43" and in java I'm wanting to get the difference from the timestamp and the current time.
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
date_def
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
date_default_timezone_set('America/New_York');
$server = timesince($row['timestamp']);
function timesince($time){
$seconds = strtotime($time) - time();
$days = floor($seconds/ -86400);
$seconds %= 86400;
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
date_default_timezone_set('America/New_York');
$server = timesince($row['timestamp']);
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
date_default_timezone_set('America/New_York');
$server = timesince($row['timestamp']);
function timesince($time){
$seconds = strtotime($time) - time();
$days = floor($seconds/ -86400);
$seconds %= 86400;time();
$days = floor($seconds/ -86400);
$seconds %= 86400;
function timesince($time){
$seconds = strtotime($time) - time();
$days = floor($seconds/ -86400);
$seconds %= 86400;
$seconds = strtotime($time) - time();
$days = floor($seconds/ -86400);
$seconds %= 86400;ault_timezone_set('America/New_York');
New to java and very unfamiliar, here is what I had in php though.... anything similar that would achieve the same thing
date_default_timezone_set('America/New_York');
$server = timesince($row['timestamp']);
function timesince($time){
$seconds = strtotime($time) - time();
$days = floor($seconds/ -86400);
$seconds %= 86400;
$minutes = floor($seconds / -60);
$seconds %= 60;
$seconds *= -1;
if ($days > 360){
return "Not voted here yet.";
}
if($days > 1){
$days = $days." days, ";
} elseif ($days == 1){
$days = $days." day, ";
} else {
$days = "";
}
if($hours > 1){
$hours = $hours." hours, ";
}elseif ($hours == 1){
$hours = $hours." hour, ";
} else {
$hours = "";
}
if($minutes > 1){
$minutes = $minutes." minutes and ";
}elseif ($minutes == 1){
$minutes = $minutes." minute and ";
}else {
$minutes = "";
}
if($seconds > 1){
$seconds = $seconds." seconds";
}elseif ($seconds == 1){
$seconds = $seconds." second";
}
return $days.$hours.$minutes.$seconds." ago";
}
I don't see anything similar to strtotime in java, and don't want to use any additional libraries.
Also in the php script I have at the top
date_default_timezone_set('America/New_York');
so it gets the right time difference with timezone accounted for.
Where to start with doing something similar in java though?
Javascript's native Date object is able to replicate php's strtodate function very easily.
To call it, you would simply use:
var d = new Date(dateString);
(See http://www.w3schools.com/jsref/jsref_obj_date.asp for more information)
So you could use a function such as:
function timesince( dateString ) {
var originalTime = new Date(); // The time you provided in milliseconds converted to javascript object
var currentTime = new Date(); // The current time as a javascript object
return millisecondDifference = parseFloat(currentTime.getTime()) - parseFloat(originalTime.getTime());
// returns the difference in milliseconds between the current time and the original time
// parseFloat is used to ensure that the values returned are read by javascript as floats (numbers) and thus can have math operations performed on them
}
to return the difference in milliseconds. Then if you'd like to convert that to "Human Readable" format, you could use a new Date object as follows:
var diffRaw = timesince( '2014-03-19 12:00:43' );
var diff = new Date(diffRaw);
var seconds = diff.getSeconds() // Seconds from 0 - 59
var minutes = diff.getMinutes() // Minutes from 0 - 59
var hours = diff.getHours() // Hours from 0 - 23
var day = diff.getDay() // Days from 0 - 6
var date = diff.getDate() // Date from 1 - 31
var month = diff.getMonth() // Months from 0 - 11
var year = diff.getFullYear() // XXXX year starting from 1970
To replicate the function you have written exactly, you could use the following function:
function timesince( dateString ) {
var originalTime = new Date(dateString);
var currentTime = new Date();
var diffRaw = millisecondDifference = parseFloat(currentTime.getTime()) - parseFloat(originalTime.getTime());
var diff = new Date(diffRaw);
var seconds = diff.getSeconds();
var minutes = diff.getMinutes();
var hours = diff.getHours();
var day = diff.getDay();
var date = diff.getDate() - 1;
var month = diff.getMonth();
var year = diff.getFullYear();
if( year !== 1970 ) {
return "Not voted here yet.";
}
var returnString = "";
if(month > 1 || month == 0) {
returnString += month + " months, ";
} else {
returnString += month + " month, ";
}
if(date > 1 || date == 0) {
returnString += date + " days, ";
} else {
returnString += date + " day, ";
}
if(hours > 1 || hours == 0) {
returnString += hours + " hours, ";
} else {
returnString += hours + " hour, ";
}
if(minutes > 1 || minutes == 0) {
returnString += minutes + " minutes, ";
} else {
returnString += minutes + " minute, ";
}
if(seconds > 1 || seconds == 0) {
returnString += seconds + " seconds, ";
} else {
returnString += seconds + " second, ";
}
return returnString;
}
You can find a working example here:
http://jsfiddle.net/MQPPw/
Don't do this in Java (or PHP, for that matter). This is something to be done in MySQL, using its date/time functions.
SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(my_timestamp_col) AS seconds_ago ...
The first method returns the current time as a unix timestamp (ie, seconds since epoch). The second method returns the my_timestamp_col time as a unix timestamp. Subtract the two, and you have how many seconds ago my_timestamp_col was.
EDIT: This gets more complicated when you factor in timezones, as Alexander points out. One option is to use the CONVERT_TZ function to get your my_timestamp_col to UTC, and then call UNIX_TIMESTAMP on that:
UNIX_TIMESTAMP(CONVERT_TZ(timestamp, '-5:00', '+0:00'))
Another option would be to do this on the Java side, after all: get the field as a Date, which should do the timezone conversion for you; then call its getTime() method to get milliseconds since epoch, and subtract that from System.currentTimeMillis(). That gives you how many milliseconds ago the event happened.
Related
Am having a doubt on how to sum total number of hours minutes seconds in java for example i have 160:00:00 and 24:00:00 and 13:50:00 and 00:10:00 i need to get grand sum like 198:00:00 how can i calculate this so far what i have tried is
for(int i=0;i<addnoteobj.size();i++){
String s = addnoteobj.get(i).getDuration();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String[] tokens = s.split(":");
int hours = Integer.parseInt(tokens[0]);
int minutes = Integer.parseInt(tokens[1]);
int seconds = Integer.parseInt(tokens[2]);
duration = 3600 * hours + 60 * minutes + seconds;
int j = duration/3600;
int h= (duration%3600) / 60;
int m = (duration % 60);
hourss=hourss+j;
mm=mm+h;
sss=sss+m;
date3 = hourss + ":" + mm + ":" + ss;
String time = simpleDateFormat.format(new Date(duration*1000L));
Log.d("dat",time);
try {
date=simpleDateFormat.parse(s);
ss=ss+date.getTime();
date3 = simpleDateFormat.format(new Date(ss));
// total=dates.getTime();
Log.d("time",date3);
} catch (ParseException e) {
e.printStackTrace();
}
}
But i cannot achieve this how to do this am having total hours in list how to get total hours thanks in advance
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenient methods were introduced.
Assuming all the string are in the form of HH:mm:ss format, you can split them on : and then combine the parts to form a string in the ISO 8601 pattern for a duration which can be parsed using Duration#parse.
Demo:
import java.time.Duration;
public class Main {
public static void main(String[] args) {
String[] strDurationArr = {
"160:00:00",
"24:00:00",
"13:50:00",
"00:10:00"
};
Duration sum = Duration.ZERO;
for (String strDuration : strDurationArr) {
sum = sum.plus(parseStrDuration(strDuration));
}
System.out.println(formatDurationJava8Plus(sum));
System.out.println(formatDurationJava9Plus(sum));
}
static Duration parseStrDuration(String strDuration) {
String[] arr = strDuration.split(":");
String strIsoDuration = "PT" + arr[0] + "H" + arr[1] + "M" + arr[2] + "S";
return Duration.parse(strIsoDuration);
}
static String formatDurationJava8Plus(Duration duration) {
return String.format("%d:%02d:%02d", duration.toHours(), duration.toMinutes() % 60, duration.toSeconds() % 60);
}
static String formatDurationJava9Plus(Duration duration) {
return String.format("%d:%02d:%02d", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
}
}
Output:
198:00:00
198:00:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I have intentionally left the println so that you can see the code flow. hope this helps you...
public static void main(String[] args) {
String time[] = { "160:00:00", "24:00:00", "13:50:00", "00:10:00" };
int hours = 0, minutes = 0, seconds = 0;
for (String string : time) {
String temp[] = string.split(":");
hours = hours + Integer.valueOf(temp[0]);
minutes = minutes + Integer.valueOf(temp[1]);
seconds = seconds + Integer.valueOf(temp[2]);
}
System.out.println(hours + ":" + minutes + ":" + seconds);
if (seconds == 60) {
minutes = minutes + 1;
seconds = 0;
} else if (seconds > 59) {
minutes = minutes + (seconds / 60);
seconds = seconds % 60;
}
System.out.println(hours + ":" + minutes + ":" + seconds);
if (minutes == 60) {
hours = hours + 1;
minutes = 0;
} else if (minutes > 59) {
hours = hours + (minutes / 60);
minutes = minutes % 60;
}
System.out.println(hours + ":" + minutes + ":" + seconds);
String output = "";
output = String.valueOf(hours);
output = output.concat(":" + (String.valueOf(minutes).length() == 1 ? "0" + String.valueOf(minutes) : String.valueOf(minutes)));
output = output.concat(":" + (String.valueOf(seconds).length() == 1 ? "0" + String.valueOf(seconds) : String.valueOf(seconds)));
System.out.println(output);
}
I didn't test it but I'm pretty sure it's something like this:
private static String sumTime(String t1, String t2){
byte extraMinutes=0;
byte extraHours=0;
String arrt1[] = t1.split(":");
String arrt2[] = t2.split(":");
int seconds = Integer.valueOf(arrt1[2]) + Integer.valueOf(arrt2[2]);
if(seconds>=60) {
extraMinutes = 1;
seconds = seconds % 60;
}
int minutes = Integer.valueOf(arrt1[1]) + Integer.valueOf(arrt2[1]) + extraMinutes;
if(minutes>=60){
extraHours = 1;
minutes = minutes % 60;
}
int hours = Integer.valueOf(arrt1[0]) + Integer.valueOf(arrt2[0]) + extraHours;
if(hours>=24) hours = hours%24;
return hours+":"+minutes+":"+seconds;
}
I need to create POSIX format of TimeZone as defined by the following format.
std offset dst [offset],start[/time],end[/time]
For ex for "America/New_York" the POSIX format is
EST+5EDT,M3.2.0/2,M11.1.0/2
Now the value M3.2.0/2 is represented in the form Mm.w.d/t.
This specifies day d of week w of month m. The day d must be between 0 (Sunday) and 6. The week w must be between 1 and 5; week 1 is the first week in which day d occurs, and week 5 specifies the last d day in the month. The month m should be between 1 and 12. I borrowed the above explanation from the following link
http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
So the above example states, the normal offset from UTC is 5 hours; since this is west of the prime meridian, the sign is positive. Summer time begins on March’s second Sunday at 2:00am and ends on November’s first Sunday at 2:00am.
When I check this in Linux timezone file /usr/share/zoneinfo/America/New_York, it matches the above value
EST5EDT,M3.2.0,M11.1.0
However when I construct this in java for timezone "America/New_York" I get the following string
EST-5EDT+1,M2.1.1/2,M10.1.1/2
I constructed the above string by extracting the information from the output of the following code.
TimeZone timezone = TimeZone.getTimeZone("America/New_York");
System.out.println(timezone.toString());
The output is as below
sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]
Notice the values endMonth=10 which should be 11 as compared to Linux output.
Relying on the output of toString is not advisable, since there are no contractual guarantees about its format in either the TimeZone or SimpleTimeZone classes.
Obviously, your month numbers are off by one; the week of the month isn’t quite as simple, since you need to take into account the first full week of the month.
I would use Java’s documented public methods to get the information:
static String posixSpecFor(TimeZone tz) {
Formatter posixSpec = new Formatter();
float offset = (float) tz.getRawOffset() / (1000 * 60 * 60) * -1;
posixSpec.format("%s%s%s",
tz.getDisplayName(false, TimeZone.SHORT),
offset >= 0 ? "+" : "",
new DecimalFormat("0.##").format(offset));
if (tz.observesDaylightTime()) {
posixSpec.format("%s", tz.getDisplayName(true, TimeZone.SHORT));
}
ZoneId zone = tz.toZoneId();
TemporalField weekOfMonth =
WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfMonth();
int thisYear = Year.now(zone).getValue();
List<ZoneOffsetTransitionRule> rules =
zone.getRules().getTransitionRules();
if (rules.size() > 2) {
rules = rules.subList(0, 2);
}
for (ZoneOffsetTransitionRule rule : rules) {
posixSpec.format(",M%d.%d.%d/%s",
rule.getMonth().getValue(),
rule.createTransition(thisYear).getDateTimeBefore().get(
weekOfMonth),
rule.getDayOfWeek().getValue() % 7,
rule.getLocalTime());
}
return posixSpec.toString();
}
Following is the complete code that I am using to construct Posix timezone string
public class PosixTimeZone {
public String toPosixTZ(String timezoneStr) {
TimeZone timezone = TimeZone.getTimeZone(timezoneStr);
sop("timezoneStr", timezoneStr);
String posixTX = "";
PosixTimeZoneData pTZData = new PosixTimeZoneData(timezone);
if (timezone.useDaylightTime()) {
posixTX = getPosixDSString(pTZData);
} else {
posixTX = getPosixString(pTZData);
}
return posixTX;
}
public static void main(String args[]) {
System.out.println("Posix TimeZone is " + new PosixTimeZone().toPosixTZ(args[0]));
}
private void sop(String varname, String meesage) {
System.out.println("**************: " + varname + " = " + meesage);
}
private String getPosixDSString(PosixTimeZoneData pTZData) {
String posixString = "";
if ((pTZData.std != null && !pTZData.std.isEmpty())
&& (pTZData.stdOffset != null)//&& !pTZData.stdOffset.isEmpty())
&& (pTZData.dst != null && !pTZData.dst.isEmpty())
&& (pTZData.dstOffset != null)// && !pTZData.dstOffset.isEmpty())
&& (pTZData.start != null && !pTZData.start.isEmpty())
&& (pTZData.end != null && !pTZData.end.isEmpty())) {
posixString = String.format("%s%s%s%s,%s,%s", pTZData.std, pTZData.stdOffset, pTZData.dst,
pTZData.dstOffset, pTZData.start, pTZData.end);
} else {
sop("Error", "Invalid Parameters");
}
return posixString;
}
private String getPosixString(PosixTimeZoneData pTZData) {
String posixString = "";
if ((pTZData.std != null && !pTZData.std.isEmpty())
&& (pTZData.stdOffset != null && !pTZData.stdOffset.isEmpty())) {
posixString = String.format("%s%s", pTZData.std, pTZData.stdOffset);
} else {
sop("Error", "Invalid Parameters");
}
return posixString;
}
class PosixTimeZoneData {
String std = "";
String stdOffset = "";
String dst = "";
String dstOffset = "";
String start = "";
String end = "";
private PosixTimeZoneData(TimeZone timeZone) {
std = timeZone.getDisplayName(false, TimeZone.SHORT);
int rawOffset = (timeZone.getRawOffset() / 3600000) * -1;
stdOffset = (rawOffset >= 0)
? ((rawOffset == 0) || (rawOffset == 1) ? "" : "+" + rawOffset)
: "" + rawOffset;
if (timeZone.useDaylightTime()) {
dst = timeZone.getDisplayName(true, TimeZone.SHORT);
int dstRawOffset = timeZone.getDSTSavings() / 3600000;
dstOffset = (dstRawOffset >= 0)
? ((dstRawOffset == 0) || (dstRawOffset == 1) ? "" : "+" + dstRawOffset)
: "" + dstRawOffset;
ZoneId zone = timeZone.toZoneId();
TemporalField weekOfMonth
= WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfMonth();
int thisYear = Year.now(zone).getValue();
List<ZoneOffsetTransitionRule> rules
= zone.getRules().getTransitionRules();
if (rules != null && !rules.isEmpty()) {
if (rules.size() > 2) {
rules = rules.subList(0, 2);
}
start = String.format("M%d.%d.%d/%s",
rules.get(0).getMonth().getValue(),
rules.get(0).createTransition(thisYear).getDateTimeBefore().get(
weekOfMonth),
rules.get(0).getDayOfWeek().getValue() % 7,
rules.get(0).getLocalTime().getHour());
end = String.format("M%d.%d.%d/%s",
rules.get(1).getMonth().getValue(),
rules.get(1).createTransition(thisYear).getDateTimeBefore().get(
weekOfMonth),
rules.get(1).getDayOfWeek().getValue() % 7,
rules.get(1).getLocalTime().getHour());
}
}
}
}
}
I want to add string time with format HH:mm:ss and special hour field. Example :
"20:15:30" (string) add "13:50:35" (string) -> result i want : "34:06:05" (string).
I have search similar code :
String time1="20:15:30";
String time2="13:50:35";
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date1 = timeFormat.parse(time1);
Date date2 = timeFormat.parse(time2);
long sum = date1.getTime() + date2.getTime();
String date3 = timeFormat.format(new Date(sum));
System.out.println("The sum is "+ date3);
And result of above code : The sum is 10:06:05 not i want. How is easy way to do this ?
You could simply take advantage of either Java 8's or Joda Time's duration capabilities.
For example, this simply creates a duration which is the sum of the number of seconds of the two times
LocalTime lt1 = LocalTime.parse("20:15:30", DateTimeFormatter.ofPattern("HH:mm:ss"));
LocalTime lt2 = LocalTime.parse("13:50:35", DateTimeFormatter.ofPattern("HH:mm:ss"));
//long t = lt1.toSecondOfDay() + lt2.toSecondOfDay();
//Duration duration = Duration.ofSeconds(t);
Duration duration = Duration.between(lt2, lt1);
System.out.println(formatDuration(duration));
Which prints out 34:06:05
formatDuration method
public static String formatDuration(Duration duration) {
long hours = duration.toHours();
duration = duration.minusHours(hours);
long minutes = duration.toMinutes();
duration = duration.minusMinutes(minutes);
long seconds = duration.getSeconds();
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
SimpleDateFormat can't do that, but you can do it yourself, by parsing the input with a regular expression, and formatting the output with the format method.
private static String addTime(String ... times) {
if (times.length < 2)
throw new IllegalArgumentException("At least 2 times are required");
Pattern timePattern = Pattern.compile("([0-9]+):([0-5][0-9]):([0-5][0-9])");
// Parse times and sum hours, minutes, and seconds
int hour = 0, minute = 0, second = 0;
for (String time : times) {
Matcher m = timePattern.matcher(time);
if (! m.matches())
throw new IllegalArgumentException("Invalid time: " + time);
hour += Integer.parseInt(m.group(1));
minute += Integer.parseInt(m.group(2));
second += Integer.parseInt(m.group(3));
}
// Handle overflow
minute += second / 60; second %= 60;
hour += minute / 60; minute %= 60;
// Format and return result
return String.format("%02d:%02d:%02d", hour, minute, second);
}
Test
System.out.println(addTime("20:15:30", "13:50:35"));
System.out.println(addTime("20:15:30", "13:50:35", "20:15:30", "13:50:35"));
System.out.println(addTime("98765:43:21", "12:34:56"));
Output
34:06:05
68:12:10
98778:18:17
I could use some help with this method I'm trying to make. I have a Problem Object, which has a target date and i need to find out how many days this problem is late divided/split by months, compared to today's date.
Image this situation:
Lets say that today's date is 05-02-2013.
ID Target date
P1 02-02-2013
P2 27-01-2013
P3 26-01-2013
P4 05-12-2012
This means that each problem is this many days late in the following months:
DEC JAN FEB
P1 3
P2 4 5
P3 5 5
P4 26 31 5
A problem can not be older than 12 months.
Now i need a method to sum these numbers storing the month name and a summed number of late days. If the target month and now month are the same, its an easy case, because i can just substract the days and store the month, but what to do when its not the case? I have the following code:
List<Problem> problems = problemQuery.getResultList(); //Problems list is already filtered and contain only late problems.
Calendar now = Calendar.getInstance();
Calendar before = Calendar.getInstance();
Map<Integer, Integer> newMap = new TreeMap<Integer, Integer>(); //map that contains month number and daysLateCount
for (Problem p : problems) {
before.setTime(p.getTarget_date());
int nowMonth = now.get(Calendar.MONTH);
int beforeMonth = before.get(Calendar.MONTH);
if (beforeMonth == nowMonth) { //easy case when both dates have same month
int result = now.get(Calendar.DAY_OF_MONTH) - before.get(Calendar.DAY_OF_MONTH);
if (newMap.containsKey(nowMonth)) {
int newLateDaysValue = newMap.get(nowMonth)+result; //get old result and add the new
newMap.put(nowMonth, newLateDaysValue);
}
else {
newMap.put(nowMonth, result);
}
}
else {
//What to do here???
}
}
Perhaps i could even skip the if-else clause and make an algorithm that could handle both cases? I don't know please help :)
The best way is to use Joda Time library: http://www.joda.org/joda-time/
Java Date/Time API is not very good and useful for such purposes.
I think there is a relatively simple solution to this, the algorithm is as follows:
import java.util.Calendar;
public class test {
public static void main(String[] args){
Calendar today = Calendar.getInstance();
Calendar problemDate = Calendar.getInstance();
today.set(2013, 01, 05);
problemDate.set(2012, 11, 05);
System.out.println(today.getTime());
System.out.println(problemDate.getTime());
// This might need further validation to make sure today >= problemDate
int diffYear = today.get(Calendar.YEAR) - problemDate.get(Calendar.YEAR);
int differenceInMonths = diffYear * 12 + today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);
//int differenceInMonths = today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);
for(int i = 0; i <= differenceInMonths; i++) {
int daysDifference;
if (differenceInMonths == 0) {
daysDifference = today.get(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
} else {
if ( i == 0) { // first month
daysDifference = problemDate.getActualMaximum(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
}
else if( i == differenceInMonths ) { // last month
daysDifference = today.get(Calendar.DAY_OF_MONTH);
}
else {
Calendar cal= Calendar.getInstance();
cal.set(Calendar.MONTH, problemDate.get(Calendar.MONTH) + i);
daysDifference = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
}
System.out.println(daysDifference);
}
}
}
Which outputs:
Tue Feb 05 14:35:43 GMT 2013
Wed Dec 05 14:35:43 GMT 2012
26
31
5
You should be able to wrap this up into your code, and in a loop fairly easily, and also remove the print statements to insert into whatever data structure you have.
A solution using Joda-Time:
LocalDate today = new LocalDate(2013, 2, 5);
LocalDate targetDate = new LocalDate(2012, 12, 5); // example with target date P4
LocalDate begin = targetDate;
LocalDate end = begin.dayOfMonth().withMaximumValue();
while (end.isBefore(today)) {
Days days = Days.daysBetween(begin, end);
if (days.getDays() > 0) {
System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
}
begin = end;
end = begin.plusDays(1).dayOfMonth().withMaximumValue();
}
end = today;
Days days = Days.daysBetween(begin, end);
if (days.getDays() > 0) {
System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
}
Prints the following result for e.g. target date P4:
December: 26
January: 31
February: 5
The year is needed, if only to know how many days are in February.
for (Problem p : problems) {
int nowYear = now.get(Calendar.YEAR);
int nowMonth = now.get(Calendar.MONTH);
int nowDay = now.get(Calendar.DAY_OF_MONTH);
before.setTime(p.getTarget_date());
int beforeYear = before.get(Calendar.YEAR);
int beforeMonth = before.get(Calendar.MONTH);
int beforeDay = before.get(Calendar.DAY_OF_MONTH);
while (beforeYear < nowYear || beforeMonth < nowMonth) {
int daysInMonth =
before.getActualMaximum(Calendar.DAY_OF_MONTH);
int result = daysInMonth - beforeDay;
Integer oldLateDaysValue = newMap.get(beforeMonth);
newMap.put(beforeMonth,
oldLateDaysValue == null ?
result : (oldLateDaysValue + result));
// For all subsequent months, calculate using entire month.
beforeDay = 0;
before.add(Calendar.MONTH, 1);
beforeYear = before.get(Calendar.YEAR);
beforeMonth = before.get(Calendar.MONTH);
}
int result = nowDay - beforeDay;
Integer oldLateDaysValue = newMap.get(beforeMonth);
newMap.put(beforeMonth,
oldLateDaysValue == null ?
result : (oldLateDaysValue + result));
}
System.out.println(newMap);
}
I'm probably just being an idiot - it's been a long day! I've misunderstood something in my first foray into Quartz...
Given this code:
DateTime dt = new DateTime();
dt = dt.withDayOfMonth(20);
Calendar cal = new CronCalendar("0 0/10 * * * ?" );
long start = dt.getMillis();
System.out.println("Starting at " + start);
long end = start + 10;
long current = start;
int i = 0;
while (current < end) {
if (i > 0) {
System.out.println(i + ":" + current);
}
long next = cal.getNextIncludedTime(current);
current = next;
i++;
}
I expect that there will be at most one included time in the output, as the time window is 10ms and the times included in the Calendar are 10 minutes apart.
But when I run it:
Starting at 1250796103004
1:1250796103005
2:1250796103006
3:1250796103007
4:1250796103008
5:1250796103009
6:1250796103010
7:1250796103011
8:1250796103012
9:1250796103013
Please help!
Yep, just me being a dumbass.
Calendars specify EXCLUDED times.
I should have been using a CronTrigger to specify the times I wanted to include. The code should look more like this...
CronTrigger cal = new CronTrigger("Test", "Test", "0 0/10 * * * ?" );
...
end = start + 1000000;
...
while (current < end) {
if (i > 0) {
System.out.println(i + ":" + current);
}
Date next = cal.getFireTimeAfter(new Date(current));
current = next.getTime();
i++;
}
Which gives the output I was expecting.
Starting at 1250798091337
1:1250798400000
2:1250799000000