2

I have followed method getDiffDateMap that calculates difference between 2 dates and returns Map of Integers that represent milliseconds, seconds, minutes, hours, days, months and years respectively.

public static Map<Integer, String> getDiffDateMap(String dateA, String dateB) {

    Calendar cal = Calendar.getInstance();      
    Map<Integer,String> out = new LinkedHashMap<Integer, String>();
    long timeInMillA = 0;
    long timeInMillB = 0;

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

    Date convertedDateA;
    Date convertedDateB;



    try {
        convertedDateA = dateFormat.parse(dateA);           
        cal.setTime(convertedDateA);
        timeInMillA = cal.getTimeInMillis();


        convertedDateB = dateFormat.parse(dateB);           
        cal.setTime(convertedDateB);
        timeInMillB = cal.getTimeInMillis();

    } catch (ParseException e) {
        e.printStackTrace();
    } 

    long mili = timeInMillB - timeInMillA;
    long sec = mili/1000;
    long min = sec/60;
    long hour = min/60;
    long day = hour/24;
    long week = day/7;
    long month = day/31; // ????
    long year = month/12;

    out.put(7, mili + "");
    out.put(6, sec + "");
    out.put(5, min + "");
    out.put(4, hour + "");
    out.put(3, day + "");
    out.put(2, week + "");
    out.put(1, month + "");
    out.put(0, year + "");

    return out;
}

My problem is to calculate month from actual day count:

long month = day/31; // or 30

For example:

Map<Integer,String> out = getDiffInMillsec("2012-9-01 20:9:01", "2012-10-01 20:10:01");

    System.out.println(Arrays.asList(out)); 

I get output: [{7=2592060000, 6=2592060, 5=43201, 4=720, 3=30, 2=4, 1=0, 0=0}] where 1 is month count and its 0. because difference is 30 days only. What flow need I add to fix this problem? Any suggestions?

Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • Your string examples are inconsistent. The minutes of the first is a single digit without a zero while other 1-9 values having a leading zero. – Basil Bourque Oct 16 '14 at 03:58

5 Answers5

6

I have followed method getDiffDateMap that calculates difference between 2 dates and returns Map of Integers that represent milliseconds, seconds, minutes, hours, days, months and years respectively.

Don't reinvent the wheel :)

Joda Time has code to do all this and more. For example:

LocalDateTime start = ...;
LocalDateTime end = ...;
Period difference = new Period(start, end, PeriodType.yearMonthDayTime());
int months = difference.getMonths(); // etc

Note that you can't get at the number of months when you've just converted the different to a number of milliseconds - as the number of months will depend on the start/end date. (30 days may or may not be a month, for example...)

I'd strongly advise you to use Joda Time throughout your Java code, in preference to java.util.*. It's a much better API, and one which will hopefully mean you rarely-if-ever need to write your own date/time handling code.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks, `Note that you can't get at the number of months when you've just converted the different to a number of milliseconds` Yes I know. I'm looking for the way without using additional `jar` (for android). In my code I still have `Date convertedDateA` and `Date convertedDateB` – Maxim Shoustin Nov 01 '12 at 20:37
  • @Fess: Well if you're using `java.util.Date` then the *first* thing you need to decide is what time zone you're in. But really, please *please* don't reinvent this wheel just for the sake of avoiding a dependency. Date and time calculations are *very hard* to get right reliably - and your code will end up being much clearer using Joda Time, too. – Jon Skeet Nov 01 '12 at 20:41
  • OK, If I haven't see any other way to do it handsomely I'll use Joda Time. Thanks – Maxim Shoustin Nov 01 '12 at 20:46
  • I don't see any solution with `Period(start, end, ...`. For example for `"01-09-2012 20:9:01", "01-10-2012 20:9:01"` as start and end I expect 1 month, 30 days, 720 hours, but I have actually 1 month, 0, days, 0 hours , 0 min ... – Maxim Shoustin Nov 02 '12 at 16:00
  • 1
    @Fess: Why would you expect 1 month and 30 days? The two dates are exactly one month apart! If you're trying to get *totals* then you should call new Period several times, with a single-unit PeriodType each time. – Jon Skeet Nov 02 '12 at 16:16
  • @MaximShoustin FYI, Joda-Time does indeed run on Android. If that is your only reason to not consider Joda-Time, take another look. – Basil Bourque Oct 16 '14 at 03:42
4

I woud suggest to use JodaTime#Months

This has a functions such as :

    static Months   monthsBetween(ReadableInstant start, ReadableInstant end) 

Creates a Months representing the number of whole months between the two specified datetimes.

    static Months   monthsBetween(ReadablePartial start, ReadablePartial end) 

Creates a Months representing the number of whole months between the two specified partial datetimes.

Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
1

I just want to conclude all what we talked before and with help of Jon Skeet, here is an answer, I used JodaTime and new Period per date value:

import org.joda.time.LocalDateTime;
import org.joda.time.Period;
import org.joda.time.PeriodType;

....
    public static Map<Integer, String> getDateTimeDiffMap(String dateA, String dateB) {

    Calendar cal = Calendar.getInstance();
    Map<Integer,String> out = new LinkedHashMap<Integer, String>();

    long timeInMillA = 0;
    long timeInMillB = 0;

    SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); 

    Date convertedDateA;
    Date convertedDateB;

    try {
    convertedDateA = dateFormat.parse(dateA);           
    cal.setTime(convertedDateA);
    timeInMillA = cal.getTimeInMillis();


    convertedDateB = dateFormat.parse(dateB);           
    cal.setTime(convertedDateB);
    timeInMillB = cal.getTimeInMillis();

} catch (ParseException e) {
    e.printStackTrace();
} 


    LocalDateTime startA = new LocalDateTime(timeInMillA);
    LocalDateTime startB = new LocalDateTime(timeInMillB);

    Period difference = new Period(startA, startB, PeriodType.days());
    int day = difference.getDays();

    difference = new Period(startA, startB, PeriodType.months());
    int month = difference.getMonths();

    difference = new Period(startA, startB, PeriodType.years());
    int year = difference.getYears();

    difference = new Period(startA, startB, PeriodType.weeks());
    int week = difference.getWeeks();

    difference = new Period(startA, startB, PeriodType.hours());
    int hour = difference.getHours();

    difference = new Period(startA, startB, PeriodType.minutes());
    long min = difference.getMinutes();

    difference = new Period(startA, startB, PeriodType.seconds());
    long sec = difference.getSeconds();

    //difference = new Period(startA, startB, PeriodType.millis());
    long mili = timeInMillB - timeInMillA;  


    out.put(7, mili + "");
    out.put(6, sec + "");
    out.put(5, min + "");
    out.put(4, hour + "");
    out.put(3, day + "");
    out.put(2, week + "");
    out.put(1, month + "");
    out.put(0, year + "");      

    return out;
}

For example for "01-09-2012 20:9:01", "01-10-2012 20:9:01" I get output:

year=0;
month = 1;
day=30;
hour=720;
...
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
1

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*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getDiffDateMap("2012-9-01 20:9:01", "2012-10-01 20:10:01"));
    }

    public static Map<Integer, String> getDiffDateMap(String dateA, String dateB) {
        Map<Integer, String> out = new LinkedHashMap<Integer, String>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
        LocalDateTime ldtA = LocalDateTime.parse(dateA, dtf);
        LocalDateTime ldtB = LocalDateTime.parse(dateB, dtf);

        out.put(7, String.valueOf(ChronoUnit.MILLIS.between(ldtA, ldtB)));
        out.put(6, String.valueOf(ChronoUnit.SECONDS.between(ldtA, ldtB)));
        out.put(5, String.valueOf(ChronoUnit.MINUTES.between(ldtA, ldtB)));
        out.put(4, String.valueOf(ChronoUnit.HOURS.between(ldtA, ldtB)));
        out.put(3, String.valueOf(ChronoUnit.DAYS.between(ldtA, ldtB)));
        out.put(2, String.valueOf(ChronoUnit.WEEKS.between(ldtA, ldtB)));
        out.put(1, String.valueOf(ChronoUnit.MONTHS.between(ldtA, ldtB)));
        out.put(0, String.valueOf(ChronoUnit.YEARS.between(ldtA, ldtB)));

        return out;
    }
}

Output:

{7=2592060000, 6=2592060, 5=43201, 4=720, 3=30, 2=4, 1=1, 0=0}

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0
    try {
        String user = request.getParameter("uname");
        out.println(user); 
        String pass = request.getParameter("pass");
        out.println(pass);
        java.sql.Date sqlDate = new java.sql.Date(new java.util.Date().getTime());

        Class.forName( "com.mysql.jdbc.Driver" );
        Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/trans","root","root" ) ;
        Statement st = conn.createStatement(); 

        String sql = "insert into purch (cd,cust,dateof) values('" + user + "','" + pass + "', '" + sqlDate + "')";
        st.executeUpdate(sql);

        Date date = new Date();
        String modifiedDate= new SimpleDateFormat("-MM-").format(date);
        String dd = modifiedDate.toString();
        String da = "ai";
        out.println(dd);

        PreparedStatement statement = conn.prepareStatement("select * from purch where  dateof LIKE ? and cd = ?");    
        statement.setString(1,"%" + dd + "%");
        statement.setString(2,"" + da + "");
        ResultSet rs = statement.executeQuery();


        if(rs != null) {
        while(rs.next()) {
            out.println(rs.getString("cd"));
            out.println(rs.getString("cust"));
            out.println(rs.getString("dateof"));
        }
        }  
    }catch(Exception e) {
        System.out.println(e.toString());
    } 
mohan
  • 1