How to sum times in Java? - java

I'm working on a report that calculates a sum of the data in it and some of the data are timestamps, for example:
----------------------
| Activity | Time |
----------------------
| 1 | 11:00:00 |
-----------------------
| 2 | 12:00:00 |
-----------------------
| 3 | 13:00:00 |
-----------------------
| Total | 36:00:00 |
----------------------
I'm trying to sum timestamps as below:
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
c.setTimeInMillis(0);
for (final String t : timestampsList) {
c.add(Calendar.MILLISECOND, (int) dt.parse(t).getTime());
}
The variable timestampsList is an ArrayList of String's, all respecting the pattern used by the SimpleDateFormat object. The problem with the given code is that I can't generate the value of the sum of the timestamps, by using the same SimpleDateFormat what I get is an hour in the pattern informed in a future date.
I also have seen Joda Time Duration class but I'm not familiar with this lib and I 'don't know if I'm in a correct path that will lead me to the right answer.
Does anyone know how to handle it by using J2SE or Joda Time?

I would just parse these Strings myself, convert them to
seconds or milliseconds and sum them up. See answer 2 below.
ANSWER 1
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Test051 {
public static void main(String[] args) throws Exception {
String pt = "1970-01-01-";
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:05");
timestampsList.add("01:00:05");
timestampsList.add("10:00:05");
final DateFormat dt = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
final Calendar sum = Calendar.getInstance();
sum.setTimeInMillis(0);
long tm0 = new SimpleDateFormat("yyyy-MM-dd").parse(pt).getTime();
System.out.println("tm0 = " + tm0);
for (final String t : timestampsList) {
// System.out.println(dt.parse(pt + t).getTime());
Date x = dt.parse(pt + t);
// System.out.println(x.getTime());
sum.add(Calendar.MILLISECOND, (int)x.getTime());
sum.add(Calendar.MILLISECOND, (int)-tm0);
}
long tm = sum.getTime().getTime();
System.out.println("tm = " + tm);
tm = tm / 1000;
long hh = tm / 3600;
tm %= 3600;
long mm = tm / 60;
tm %= 60;
long ss = tm;
System.out.println(format(hh) + ":" + format(mm) + ":" + format(ss));
}
private static String format(long s){
if (s < 10) return "0" + s;
else return "" + s;
}
}
ANSWER 2
import java.util.ArrayList;
public class Test051 {
public static void main(String[] args) throws Exception {
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:05");
timestampsList.add("01:00:05");
timestampsList.add("10:00:05");
long tm = 0;
for (String tmp : timestampsList){
String[] arr = tmp.split(":");
tm += Integer.parseInt(arr[2]);
tm += 60 * Integer.parseInt(arr[1]);
tm += 3600 * Integer.parseInt(arr[0]);
}
long hh = tm / 3600;
tm %= 3600;
long mm = tm / 60;
tm %= 60;
long ss = tm;
System.out.println(format(hh) + ":" + format(mm) + ":" + format(ss));
}
private static String format(long s){
if (s < 10) return "0" + s;
else return "" + s;
}
}
ANSWER 3
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Test051 {
public static void main(String[] args) throws Exception {
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:00");
timestampsList.add("02:00:00");
timestampsList.add("03:00:00");
timestampsList.add("04:00:00");
timestampsList.add("02:00:00");
timestampsList.add("04:00:00");
Date dt0 = new SimpleDateFormat("yyyy-MM-dd").parse("1970-01-01");
// Check very carefully the output of this one.
System.out.println(dt0.getTime());
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance();
c.setTimeInMillis(0);
for (final String t : timestampsList) {
c.add(Calendar.MILLISECOND, (int) dt.parse(t).getTime());
c.add(Calendar.MILLISECOND, (int)-dt0.getTime());
}
// We need to add this back. This is basically the time zone offset.
c.add(Calendar.MILLISECOND, (int)dt0.getTime());
System.out.println(c.getTime().getTime());
System.out.println(c.getTimeInMillis());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()));
System.out.println(new SimpleDateFormat("HH:mm:ss").format(c.getTime()));
}
}

If you don't wanna use peter petrov solution to parse your String yourself, the way to do it with Calendar and SimpleDateFormat is as follow :
List<String> timestampsList = new ArrayList<String>();
timestampsList.add("11:00:00");
timestampsList.add("12:00:00");
timestampsList.add("13:00:00");
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
long milliseconds = 0;
c.clear();
long startingMS = c.getTimeInMillis();
for (final String t : timestampsList) {
milliseconds = milliseconds + (dt.parse(t).getTime() - startingMS);
}
System.out.println(milliseconds + " milliseconds");
System.out.println(milliseconds / 1000 + " seconds");
System.out.println(milliseconds / 1000 / 60 + " minutes");
System.out.println(milliseconds / 1000 / 60 / 60 + " hours");
Or use
long startingMS = dt.parse("00:00:00").getTime();
for (final String t : timestampsList) {
milliseconds = milliseconds + (dt.parse(t).getTime() - startingMS);
}
instead, removing the need for the Calendar.
Both result in :
129600000 milliseconds
129600 seconds
2160 minutes
36 hours
Note that you might wanna make the results a double not to miss part of the time.

This is a original code from petrov with some edits made by me. Since it's quite dificult to discuss in comments providing big snippets of code I posted it as an answer so we can discuss petrov's other considerations.
public static void somaTempos(final String[] listaTempos) throws ParseException {
long tm = 0;
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
for (String tmp : listaTempos) {
c.setTime(dt.parse(tmp));
tm += c.get(Calendar.SECOND) + 60 * c.get(Calendar.MINUTE) + 3600 * c.get(Calendar.HOUR_OF_DAY);
}
final long l = tm % 3600;
System.out.println(SIGRUtil.format(tm / 3600) + ':' + SIGRUtil.format(l / 60) + ':' + SIGRUtil.format(l % 60));
}
private static String format(long s) {
if (s < 10) {
return "0" + s;
}
return String.valueOf(s);
}
UPDATE: An alternative that also solves my problem:
public static String sumTimes(final String[] timestampList) {
long milliseconds = 0;
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
dt.setLenient(false);
try {
final long timezoneOffset = dt.parse("00:00:00").getTime();
for (final String t: timestampList) {
milliseconds += (dt.parse(t).getTime() - timezoneOffset);
}
} catch (final ParseException e) {
throw new BusinessException(
"One of the timestamps in the timestamp list cannot be applied to the HH:mm:ss pattern.", e);
}
((SimpleDateFormat) dt).applyPattern(":mm:ss");
return new StringBuilder(8).append(milliseconds / 3600000).append(
dt.format(new Date(milliseconds))).toString();
}
Actually, the API gives me for free the minutes and the seconds by only reaplying another pattern in the DateFormat after calculating the sum of the time stamps, without forgetting to consider the timezone offset in this calculation, my real problem was how to calculate the number of hours which really is the less dificult part.
Any suggestions of improvements?

If those data input Strings represent durations in hours:minutes:seconds without any date or time-of-day, then the other answers are working much too hard.
Generally, the old java.util.Date and .Calendar classes are notoriously troublesome and should be avoided. Specifically here, those classes have no notion of a span of time. Instead you should be using either Joda-Time or maybe java.time.
Joda-Time
Joda-Time offers three classes to represent a span of time: Interval, Period, and Duration. The first is tied to points along the timeline of the Universe. The other two are not.
The Period and Duration classes are very close cousins. Period is a tuple with a number of years, months, days, hours, minutes, and seconds. Duration is a number of milliseconds with no concept of fields such as days or seconds.
Joda-Time uses the ISO 8601 standard for its defaults in parsing and generating strings. For period/duration time, this means the PnYnMnDTnHnMnS format. The P means "period" and the T is a separator between date and time portions.
Here is some example code in Joda-Time 2.3. Basically a couple of lines: parsePeriod & durationSum.plus seen below.
Simulate input strings.
List<String> durationStrings = new ArrayList<String>();
durationStrings.add( "11:00:00" ); // Number of hours/minutes/seconds. Not time-of-day.
durationStrings.add( "12:00:00" );
durationStrings.add( "13:00:00" ); // Expect sum of 36 hours = 11 + 12 + 13.
Define a formatter to parse those strings. Joda-Time might have such a formatter built-in, but I could not locate it. So I defined one.
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendHours()
.appendSeparator( ":" )
.appendMinutes()
.appendSeparator( ":" )
.appendSeconds()
.toFormatter();
Loop the input strings, parsing each one, then adding its duration to the sum.
Duration durationSum = Duration.ZERO; // Initializing to empty amount. Add to this in loop below.
for ( String durationString : durationStrings ) {
Period period = formatter.parsePeriod( durationString );
Duration duration = period.toStandardDuration();
durationSum = durationSum.plus( duration );
System.out.println( "period: " + period );
System.out.println( "duration: " + duration );
}
System.out.println( "durationSum: " + durationSum );
System.out.println( "durationSum as Period: " + durationSum.toPeriod() );
When run…
period: PT11H
duration: PT39600S
period: PT12H
duration: PT43200S
period: PT13H
duration: PT46800S
durationSum: PT129600S
durationSum as Period: PT36H

Related

calculate elapsed time and display it in Java

There seems to be no easy answer in stackoverflow for this problem. I simply want to get the difference between two Calendar instances and display in HH:mm:ss.SSS
So far, I have
SimpleDateFormat dateFormat = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar start = Calendar.getInstance();
say("start time:"+dateFormat.format(start.getTime()));
and
Calendar ending = Calendar.getInstance();
say("ending time:"+dateFormat.format(ending.getTime()));
long milli = ending.getTime().getTime()
- start.getTime().getTime();
long sec = milli / 1000; // millisec to sec
say("elapsed time: " + sec + "." + milli );
which does work to display the two times.
start time: 2018-03-02 15:44:41.194
*** program runs ***
ending time:2018-03-02 15:44:41.198
elapsed time: 0.4
But shouldn't it be saying 0.004 seconds?
And PLEASE no JodaTime answers. This shop does not support that.
Instant start = Instant.now();
And
Instant end = Instant.now();
long milli = ChronoUnit.MILLIS.between(start, end);
System.out.format(Locale.ENGLISH, "elapsed time: %.3f%n", milli / 1000.0);
On my computer this printed
elapsed time: 0.004
Formatting with String.format or System.out.format() also works with your way of measuring the milliseconds, of course.
Using Java 9 you can (at least on some computers) have more decimals if you want:
System.out.println("elapsed time: "
+ ChronoUnit.NANOS.between(start, end) / (double) TimeUnit.SECONDS.toNanos(1));
I got
elapsed time: 0.003739
I wrote a little function for you, it returns a number as a string filled with as many "0" as you want.
public String getStringNumber(long number, int displaySize) {
String str = new String();
int length = String.valueOf(number).length();
while (length++ < displaySize)
str += "0";
str += number;
return str;
}
Now you can just replace in your code
say("elapsed time: " + sec + "." + getStringNumber(milli, 4));
I finally arrived on this solution. It is awkward and not very elegant, but it works.
Calendar ending = Calendar.getInstance();
say("ending time:"+dateFormat.format(ending.getTime()));
long milli = ending.getTime().getTime()
- start.getTime().getTime();
long hrs = TimeUnit.MILLISECONDS.toHours(milli) % 24;
long
min = TimeUnit.MILLISECONDS.toMinutes(milli) % 60;
long sec
= TimeUnit.MILLISECONDS.toSeconds(milli) % 60;
long mls = milli % 1000;
String elaps =
String.format("%02d:%02d:%02d.%03d", hrs,
min, sec, mls);
say("Elapsed time: " + elaps);
Here is the explanation: I convert the two Calendar variables to long, and subtract. Then I format the Long to a string in format hh:mm:ss.SSS which is what I wanted in the first place.
Here is the output
ending time:2018-03-05 15:07:17.923
Elapsed time: 00:01:15.964
Okay, so, simply off the top of my head, without trying to perform anything kind of fancy, you could make use of the Java 8 date/time API, which provides the capability to calculate the different between two points in time.
So, taking your input, and running it through the code below, it outputs
2018-03-02T15:44:41.194
2018-03-02T15:44:41.198
0.004
Now, personally, I'd take the concept and simply create a DurationFormatter which could take a Duration and spit out your required format, but the idea here is to give you a jumping point to start from.
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-02 15:44:41.198";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
System.out.println(startDateTime);
System.out.println(endDateTime);
Duration duration = Duration.between(startDateTime, endDateTime);
long hours = duration.toHours();
duration = duration.minusHours(hours);
long mins = duration.toMinutes();
duration = duration.minusMinutes(mins);
long secs = duration.getSeconds();
duration = duration.minusSeconds(secs);
long millis = duration.toMillis();
StringBuilder sb = new StringBuilder(12);
if (hours > 0) {
sb.append(pad(hours, 2));
}
if (mins == 0 && sb.length() > 0) {
sb.append(":00");
} else if (mins > 0) {
if (hours > 0) {
sb.append(":");
}
sb.append(pad(mins, 2));
}
if (secs == 0 & sb.length() > 0) {
sb.append(":00");
} else if (secs > 0) {
if (mins > 0) {
sb.append(":");
}
sb.append(pad(secs, 2));
}
if (millis == 0 & sb.length() > 0) {
sb.append(".00");
} else if (millis > 0) {
if (secs > 0 || sb.length() > 0) {
sb.append(".");
} else if (sb.length() == 0) {
sb.append("0.");
}
sb.append(pad(millis, 3));
}
System.out.println(sb.toString());
}
public static String pad(long value, long length) {
return String.format("%0" + length + "d", value);
}
}
Now, if we change the input to something like...
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:44:41.198";
It outputs
144:00:00.004
Or if we use
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:41.198";
It outputs
143:31:00.004
Or
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:50.198";
It outputs
143:31:09.004
Or
2018-03-02T15:44:41.194
2018-03-02T15:50:41.194
It outputs
06:00.00
... to me, this is where it gets weird, technically it's correct (6 mins), but from the format, it's hard to deduce exactly what it means
This is where I might be tempted to use something more like String.format("%02d:%02d:%02d.%04d", hours, mins, secs, millis) which will output 00:06:00.0000, but that all comes do to you needs. You will need to decide how best to take the raw information and present it based on your needs, but there are a couple of different ideas

Converting number of days(int) into days,months and years in java (including leap year)

I used this code to convert number of days into respecting days,months and year
But the result are not precise because i don't take account for leap year and month with 31 days
What is the best way to solve/encounter this issue
field_Date1 and field_Date2 are input from my program
duration=field_Date2-field_Date1
duration is the number of days(int b)
In the if else i do the conversion(but the condition are not precise)
import java.util.concurrent.TimeUnit;
import java.math.RoundingMode;
import java.text.DecimalFormat;
if (field_Date1 == null || field_Date2 == null){
return "";
} else {
Date startDate = (Date)field_Date1;
Date endDate = (Date)field_Date2;
long duration = endDate.getTime() - startDate.getTime();
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);
long diff = duration - TimeUnit.DAYS.toMillis(diffInDays);
double diffToHours = TimeUnit.MILLISECONDS.toHours(diff);
float hoursToDay = (float) (diffToHours / 24.0);
float a =hoursToDay+diffInDays;
a=Math.floor(a)
int b = (int)a
if(b<30)
{
StringBuilder sb = new StringBuilder("Day: ")
sb.append(b)
String c = sb.toString()
c
}
else if(b<366)
{
int months = b/30
int days_out=b%30
StringBuilder p1 = new StringBuilder("Days: ")
StringBuilder p2 = new StringBuilder("Months: ")
StringBuilder p3 = new StringBuilder(" ")
p1.append(days_out)
p2.append(months)
p2.append(p3)
p2.append(p1)
String c=p2.toString()
c
}
else
{
StringBuilder p1 = new StringBuilder("Months: ")
StringBuilder p2 = new StringBuilder("Years: ")
StringBuilder p3 = new StringBuilder(" ")
StringBuilder p4 = new StringBuilder("Days: ")
int years = b/365
int days_out=b%365
if(days_out>30)
{
int m1 = days_out/30
int m2 = days_out%30
p2.append(years)
p1.append(m1)
p4.append(m2)
p2.append(p3)
p2.append(p1)
p2.append(p3)
p2.append(p4)
String hj = p2.toString()
return hj
}
else
{
p4.append(days_out)
p2.append(years)
p2.append(p3)
p2.append(p4)
String c=p2.toString()
return c
}
}
}
Joda-Time
Try using Joda-Time 2.5:
Snippet will look something like this:
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;
Date startDate = (Date)field_Date1;
Date endDate = (Date)field_Date2;
int days = Days.daysBetween( new DateTime(startDate), new DateTime(endDate) ).getDays();
java.time
Or the following method from java.time (Java8) can be used:
public static Period between(LocalDate startDateInclusive,
LocalDate endDateExclusive)
This obtains a period between two dates, consisting of the number of years, months, and days.
If you want the difference between two dates in days, including taking into account leap years etc, the java.time package (new in Java 8) gives you:
LocalDate firstDate = LocalDate.of(2014, Month.DECEMBER, 1);
LocalDate secondDate = LocalDate.of(2016, Month.MARCH, 12);
long days = firstDate.until(secondDate,ChronoUnit.DAYS);
gives you 467 days.
Alternatively,
Period period = firstDate.until(secondDate);
will give you a Period object, which stores the time broken down into years, months and days ie. instead of 467 days, you get 1 year, 3 months and 11 days. This is good for human readability. However, if you want the total days, it's not easy to get that from the Period object, so you're better off going with the first option I gave.

easy calculation of weeks of certain period with java

Is there any easy library or approach to get the week (from which date ~ date) of certain periods?
Example:
There is 6 weeks(variable) (start from 1 July, 2012 ~ 11 Aug, 2012).
I want to cut off the 6 weeks into 2 portions (variable). So the results will be
1) 1 July,2012 ~ 21 July, 2012
2) 22 July,2012 ~ 11 Aug, 2012... etc
With jodatime, I can easily get the number of weeks between certain periods though.
All I know is Start Date and End Date which both are variables and cutoffweeks amount(eg.6 weeks or 4 weeks).
final LocalDate start = new LocalDate();
final LocalDate end3 = start.plusWeeks(3)
Its not exactly clear what you want, but Joda-Time makes most things rather easy.
I guess you need something like :
public void doStruff(int cutOff){
int portion = cutoff/2;
final LocalDate start = new LocalDate();
final LocalDate end = start.plusWeeks(portion)
}
you can try this code:
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateDiff {
public static void main(String[] args) {
String s1 = "06/01/2012";
String s2 = "06/24/2012";
DateDiff dd = new DateDiff();
Date then = null, now = null;
DateFormat df = DateFormat.getInstance();
df.setTimeZone( TimeZone.getDefault() );
try {
then = df.parse( s1 + " 12:00 PM" );
now = df.parse( s2 + " 12:00 PM" );
} catch ( ParseException e ) {
System.out.println("Couldn't parse date: " + e );
System.exit(1);
}
long diff = dd.getDateDiff( now, then, Calendar.WEEK_OF_YEAR );
System.out.println("No of weeks: " + diff );
}
long getDateDiff( Date d1, Date d2, int calUnit ) {
if( d1.after(d2) ) { // make sure d1 < d2, else swap them
Date temp = d1;
d1 = d2;
d2 = temp;
}
GregorianCalendar c1 = new GregorianCalendar();
c1.setTime(d1);
GregorianCalendar c2 = new GregorianCalendar();
c2.setTime(d2);
for( long i=1; ; i++ ) {
c1.add( calUnit, 1 ); // add one day, week, year, etc.
if( c1.after(c2) )
return i-1;
}
}
}

Get time with hour, minute, second, millisecond, microsecond

I have this code:
SimpleDateFormat sDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
I know that this code return hour, minute, second in the time.
How i can get also the millisecond and microsecond??
You won't have microseconds, because a Date stores the number of milliseconds since Jan. 1 1970. For the milliseconds, use S, as documented in the javadoc.
The only way to get micro-seconds is to parse the string yourself. Note: Date should be used to store micro-seconds, but you can use a long. (which you can also use for milli-seconds or nano-seconds)
private static final String YEARS_TO_MINUTES = "yyyy-MM-dd HH:mm";
private static final SimpleDateFormat YEARS_TO_MINUTES_SDF = new SimpleDateFormat(YEARS_TO_MINUTES);
public static long parseMicroSeconds(String text) throws ParseException {
long timeMS;
synchronized (YEARS_TO_MINUTES_SDF) {
timeMS = YEARS_TO_MINUTES_SDF.parse(text.substring(0, YEARS_TO_MINUTES.length())).getTime();
}
long microSecs = 0;
if (text.length() > YEARS_TO_MINUTES.length() + 1) {
double secs = Double.parseDouble(text.substring(YEARS_TO_MINUTES.length() + 1));
microSecs = (long) (secs * 1e6 + 0.5);
}
return timeMS * 1000 + microSecs;
}
public static String formatMicroSeconds(long timeMicroSeconds) {
String dateTime;
synchronized (YEARS_TO_MINUTES_SDF) {
dateTime = YEARS_TO_MINUTES_SDF.format(new Date(timeMicroSeconds / 1000));
}
long secs = timeMicroSeconds % 60000000;
return dateTime + String.format(":%09.6f", secs / 1e6);
}
public static void main(String... args) throws ParseException {
String dateTime = "2011-01-17 19:27:59.999650";
long timeUS = parseMicroSeconds(dateTime);
for (int i = 0; i < 5; i++)
System.out.println(formatMicroSeconds(timeUS += 175));
}
prints
2011-01-17 19:27:59.999825
2011-01-17 19:28:00.000000
2011-01-17 19:28:00.000175
2011-01-17 19:28:00.000350
2011-01-17 19:28:00.000525
You can do similarly if you need nano-timings.
The best you can do is:
SimpleDateFormat sDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
You can only show the millisecond: :SS.
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class MyClass
{
public static void main(String args[]) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss:SSSSS");
for(int i=0; i<=5;i++) {
System.out.println("Class 1 : " + ZonedDateTime.now().format(formatter));
}
}
}
Example output:
Class 1 : 19:25:19:77336
Class 1 : 19:25:19:77483
Class 1 : 19:25:19:77487
Class 1 : 19:25:19:77490
Class 1 : 19:25:19:77493
Class 1 : 19:25:19:77496
Check the Java-doc of SimpleDateFormat, it tells :
Millisecond : S
Microseconds are not available.
This example gets millisecond. Microseconds isn't available.
Date someDate = sDate.parse(dateString);
Calendar c = Calendar.setTime(someDate);
int millisecond = c.get(Calendar.MILLISECOND);
Generally the milliseconds are given with capital s and in your case it will be yyyy-MM-dd HH:mm:ss:SSS. For more info refer to Customizing formats

Creating a custom week counter in Java?

I am trying to create a custom week counter but am having quite a lot of trouble and feel like I am going about it all wrong. The method should take in a string date that is in yyyy-MM-dd format and return the week number. The week counter started October 1, 2000. The week starts Friday and ends Thursday. The first 2 digits represents the years and the second 2 represent the week. So this week would be 1143 (11 to represent the year and 43 to represent the weeks since Oct 1).
This is what I have gotten so far:
public static String get_week(String date){
try{
Calendar first_dt = Calendar.getInstance();
first_dt.set(1999, 10, 01);
long first_dt_milliseconds = first_dt.getTimeInMillis();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date format_date = (Date)formatter.parse(date);
SimpleDateFormat month = new SimpleDateFormat("MM");
SimpleDateFormat year = new SimpleDateFormat("yyyy");
long drop_dt_milliseconds = format_date.getTime() - first_dt_milliseconds;
long drop_dt_years = drop_dt_milliseconds / (24 * 60 * 60 * 1000) / 365;
Calendar year_ago = Calendar.getInstance();
year_ago.set(Integer.parseInt(year.format(format_date))-1, 10, 01);
long year_ago_milliseconds = year_ago.getTimeInMillis();
long year_ago_diff = format_date.getTime() - year_ago_milliseconds;
year_ago_diff = year_ago_diff / (24 * 60 * 60 * 1000) / 7;
if (month.format(format_date).equals("10") || month.format(format_date).equals("11") || month.format(format_date).equals("12")){
date = drop_dt_years+1+""+year_ago_diff;
}
else{
date = year_ago_diff;
}
}catch(Exception e){
e.printStackTrace();
}
return date;
}
I used Joda-Time because it's less confusing than Java's built-in date and time gear
EDIT - new code, rolled in ChssPly's suggestion and fixed a problem with the weeks between Oct 1 and Jan 1. Also check out X-Zero's suggestion to create a custom Chronology in Joda-Time, might be an interesting approach.
import org.joda.time.DateMidnight;
import org.joda.time.Weeks;
import org.joda.time.Years;
public class Main {
private String getWeek (DateMidnight dt2) {
DateMidnight dt = new DateMidnight(2000,10,1);
// First get the number of elapsed years, ChssPly76's way
int yearz = Years.yearsBetween(dt, dt2).getYears();
/*
* We now need the number of weeks in the current year, which can be
* calculated using the Weeks class.
*/
int yearOffset = 1;
// But if the new date is Oct 1 thru Dec 12 year must remain the same
if (!dt2.isBefore (new DateMidnight(dt2.getYear(),10,1))) {
yearOffset = 0;
}
int weekz = Weeks.weeksBetween(dt.withYear(dt2.getYear()-yearOffset), dt2).getWeeks();
return(yearz + " " + weekz);
}
private void test (DateMidnight testDate) {
System.out.println("For date " + testDate + " years/weeks = " + getWeek(testDate));
}
private void run() {
test (new DateMidnight());
test (new DateMidnight(2010,10,8));
test (new DateMidnight(2010,9,30));
test (new DateMidnight(2000,10,1));
}
public static void main(String[] args) {
new Main().run();
}
}
Which outputs
For date 2011-07-26T00:00:00.000+02:00 years/weeks = 10 42
For date 2010-10-08T00:00:00.000+02:00 years/weeks = 10 1
For date 2010-09-30T00:00:00.000+02:00 years/weeks = 9 52
For date 2000-10-01T00:00:00.000+02:00 years/weeks = 0 0
Probably a slightly more sophisticated return object would be better....

Categories

Resources