سؤال

أنا أستخدم جافا java.util.Date فئة في سكالا وتريد مقارنة أ Date الكائن والوقت الحالي.أعلم أنه يمكنني حساب الدلتا باستخدام getTime():

(new java.util.Date()).getTime() - oldDate.getTime()

ومع ذلك، هذا يتركني مع long تمثل ميلي ثانية.هل هناك أي طريقة أبسط وأجمل للحصول على دلتا الوقت؟

هل كانت مفيدة؟

المحلول

JDK Date API مكسورة بشكل فظيع للأسف. أوصي باستخدام مكتبة تايم جودا.

تايم Joda لديه مفهوم للوقت فترة:

Interval interval = new Interval(oldTime, new Instant());

تحرير: بالمناسبة ، لدى جودا مفهومين: Interval لتمثيل فترة زمنية بين مدة مرتين (تمثل الوقت بين الساعة 8 صباحًا و 10 صباحًا) ، و Duration وهذا يمثل طول الوقت دون الحدود الزمنية الفعلية (على سبيل المثال تمثل ساعتين!)

إذا كنت تهتم فقط بمقارنة الوقت ، معظمها Date التطبيقات (بما في ذلك JDK واحد) تنفذ Comparable الواجهة التي تتيح لك استخدام Comparable.compareTo()

نصائح أخرى

فرق بسيط (بدون lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

ثم يمكنك الاتصال:

getDateDiff(date1,date2,TimeUnit.MINUTES);

للحصول على صرف التواريخ 2 في وحدة الدقائق.

TimeUnit هو java.util.concurrent.TimeUnit, ، تعداد جافا القياسي من نانو إلى أيام.


الفرق القابل للقراءة البشرية (بدون ليب)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {

        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://eadeone.com/5dxeu6

الإخراج شيء مثل Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, ، مع الوحدات المطلوبة.

عليك فقط تحويل هذه الخريطة إلى سلسلة سهلة الاستخدام.


تحذير

قصاصات الكود أعلاه تحسب فرقًا بسيطًا بين 2 من المثاليين. يمكن أن يسبب مشاكل أثناء مفتاح توفير ضوء النهار ، كما هو موضح في هذا المشنور. هذا يعني أنه إذا قمت بحساب الفرق بين التواريخ دون وقت قد يكون لديك يوم/ساعة مفقودة.

في رأيي ، فإن تاريخ Diff هو نوع من الشخصيات ، خاصة في الأيام. يمكنك:

  • عد عدد 24 ساعة المنقضي: اليوم+1 - يوم = 1 يوم = 24 ساعة

  • عد عدد الوقت المنقضي ، مع رعاية مدخرات ضوء النهار: اليوم+1 - اليوم = 1 = 24 ساعة (ولكن باستخدام وفورات منتصف الليل وضوء النهار ، يمكن أن يكون 0 يوم و 23 ساعة)

  • عد عدد day switches, ، مما يعني اليوم+1 مساءً - اليوم 11 صباحًا = 1 يوم ، حتى لو كان الوقت المنقضي فقط 2 ساعة (أو 1 ساعة إذا كان هناك توفير ضوء النهار: P)

إجابتي صالحة إذا كان تعريف DITF Diff في الأيام يتطابق مع الحالة الأولى

مع jodatime

إذا كنت تستخدم Jodatime ، فيمكنك الحصول على Diff لمحظتين (جيلز مدعوم قراءًا).

Interval interval = new Interval(oldInstant, new Instant());

ولكن يمكنك أيضًا الحصول على فرق التواريخ/الأوقات المحلية:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

لاحظ أن هذا يعمل مع تواريخ UTC ، وبالتالي قد يكون الفرق يومًا في إجازة إذا نظرت إلى التواريخ المحلية. يتطلب تشغيلها بشكل صحيح مع التواريخ المحلية نهجًا مختلفًا تمامًا بسبب وقت التوفير في ضوء النهار.

تحتاج إلى تحديد مشكلتك بشكل أكثر وضوحًا. أنت يستطع فقط خذ عدد المللي ثانية بين الاثنين Date الكائنات وتقسيمها على عدد المللي ثانية في 24 ساعة ، على سبيل المثال ... ولكن:

  • هذا لن يستغرق مناطق الوقت في الاعتبار - Date دائما في UTC
  • لن يستغرق هذا وقت التوفير في ضوء النهار (حيث يمكن أن يكون هناك أيام يبلغ طولها 23 ساعة فقط ، على سبيل المثال)
  • حتى في UTC ، كم عدد الأيام الموجودة في 16 أغسطس 11 مساءً إلى 18 أغسطس من 2 صباحًا؟ إنه 27 ساعة فقط ، فهل هذا يعني يومًا ما؟ أم يجب أن يكون ثلاثة أيام لأنه يغطي ثلاثة تواريخ؟

باستخدام Java.Time إطار عمل مدمج في Java 8+:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

انتاج:

ISO-8601: PT24H10M

الدقائق: 1450

لمزيد من المعلومات ، انظر تعليمي أوراكل و ال ISO 8601 اساسي.

ليرة تركية ؛ د

تحويل عفا عليها الزمن الخاص بك java.util.Date كائنات لاستبدالها، java.time.Instant.ثم احسب الوقت المنقضي كـ a Duration.

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;

د.toString ():PT2H34M56S

د.toMinutes():154

د.toMinutesPart ():34

تنسيق ايزو 8601: PnYnMnDTnHnMnS

المعيار المعقول ايزو 8601 يحدد تمثيلًا نصيًا موجزًا ​​لفترة زمنية بعدد السنوات والأشهر والأيام والساعات وما إلى ذلك.يستدعي المعيار مثل هذا النطاق أ مدة.التنسيق هو PnYnMnDTnHnMnS أين ال P يعني "الفترة"، و T يفصل جزء التاريخ عن جزء الوقت، وبينهما أرقام متبوعة بحرف.

أمثلة:

  • P3Y6M4DT12H30M5S
    ثلاث سنوات وستة أشهر وأربعة أيام واثنتي عشرة ساعة وثلاثين دقيقة وخمس ثوان
  • PT4H30M
    أربع ساعات ونصف

java.time

ال java.time إطار عمل مدمج في Java 8 ويحل لاحقًا محل الإطار القديم المزعج java.util.Date/java.util.Calendar الطبقات.الفصول الجديدة مستوحاة من الناجحين للغاية جودا تايم إطار العمل، المقصود منه أن يكون خليفته، مشابهًا في المفهوم ولكن تمت إعادة تصميمه.تم تعريفه بواسطة جي إس آر 310.ممتدة من ثلاثة عشرة اضافية مشروع.انظر درس تعليمي.

لحظة

ال Instant يمثل الفصل لحظة على الجدول الزمني في التوقيت العالمي مع قرار نانو ثانية (ما يصل إلى تسعة (9) أرقام من الكسر العشري).

Instant instant = Instant.now() ;  // Capture current moment in UTC.

من الأفضل تجنب الفئات القديمة مثل Date/Calendar.ولكن إذا كان يجب عليك التعامل مع الكود القديم الذي لم يتم تحديثه بعد java.time, ، تحويل ذهابا وإيابا.استدعاء طرق التحويل الجديدة المضافة إلى الفئات القديمة.للانتقال من أ java.util.Date إلى Instant, ، يتصل Date::toInstant.

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

فترة زمنية

قسمت فئات Java.time فكرة تمثيل فترة زمنية بعدد من السنوات والأشهر والأيام والساعات والدقائق والثواني إلى نصفين:

  • Period لسنوات، أشهر، أيام
  • Duration للأيام والساعات والدقائق والثواني

هنا مثال.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

تفريغ إلى وحدة التحكم.

كلاهما Period و Duration استخدم ال ايزو 8601 معيار لإنشاء تمثيل سلسلة لقيمتها.

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );

الآن:2015-11-26T00:46:48.016-05:00[أمريكا/مونتريال] إلى المستقبل:2015-11-26T00:46:48.016-05:00[أمريكا/مونتريال] = PT1H3M

يضيف Java 9 طرقًا إلى Duration للحصول على جزء الأيام وجزء الساعات وجزء الدقائق وجزء الثواني.

يمكنك الحصول على إجمالي عدد الأيام أو الساعات أو الدقائق أو الثواني أو المللي ثانية أو النانو ثانية في المدة بأكملها.

long totalHours = duration.toHours();

في جافا 9 Duration يحصل الفصل على أساليب جديدة لإرجاع الأجزاء المختلفة من الأيام والساعات والدقائق والثواني والميلي ثانية/النانو ثانية.اتصل ب to…Part طُرق: toDaysPart(), toHoursPart(), ، وما إلى ذلك وهلم جرا.

ChronoUnit

إذا كنت تهتم فقط بتفاصيل زمنية أبسط وأكبر، مثل "عدد الأيام المنقضية"، فاستخدم ChronoUnit التعداد.

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

مثال آخر.

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );

120


حول جافا.تايم

ال java.time إطار العمل مدمج في Java 8 والإصدارات الأحدث.تحل هذه الفئات محل الفئات القديمة المزعجة إرث فئات التاريخ والوقت مثل java.util.Date, Calendar, & SimpleDateFormat.

ال جودا تايم المشروع، الآن في نمط الصيانة, ينصح بالانتقال إلى Java.time.

لمعرفة المزيد، راجع أوراكل البرنامج التعليمي.وابحث في Stack Overflow عن العديد من الأمثلة والشروحات.المواصفات هي جي إس آر 310.

أين يمكن الحصول على دروس Java.time؟

ال ثلاثة عشرة اضافية يقوم المشروع بتوسيع Java.time بفئات إضافية.يعد هذا المشروع بمثابة أرض اختبار للإضافات المستقبلية المحتملة إلى java.time.قد تجد بعض الفئات المفيدة هنا مثل Interval, YearWeek, YearQuarter, ، و أكثر.


جودا تايم

تحديث:ال جودا تايم المشروع موجود الآن نمط الصيانة, ، حيث ينصح الفريق بالهجرة إلى java.time الطبقات.أترك هذا القسم سليما للتاريخ.

تستخدم مكتبة Joda-Time ISO 8601 لإعداداتها الافتراضية.إنه Period يقوم الفصل بتوزيع وإنشاء سلاسل PnYnMnDTnHnMnS هذه.

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

يجعل:

period: PT4H30M
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-ime/faq.html#datediff

بديل أبسط قليلاً:

System.currentTimeMillis() - oldDate.getTime()

أما بالنسبة لـ "أجمل": حسنًا ، ما الذي تحتاجه بالضبط؟ المشكلة في تمثيل فترات الوقت كعدد من الساعات والأيام وما إلى ذلك هي أنها قد تؤدي إلى عدم الدقة والتوقعات الخاطئة بسبب تعقيد التواريخ (مثل الأيام يمكن أن يكون لها 23 أو 25 ساعة بسبب وقت التوفير في ضوء النهار).

يمكن أن يؤدي استخدام نهج المللي ثانية إلى حدوث مشاكل في بعض اللغات.

دعنا نأخذ ، على سبيل المثال ، الفرق بين التاريخين 03/24/2007 و 03/25/2007 يجب أن يكون يوم واحد ؛

ومع ذلك ، باستخدام مسار ميلي ثانية ، ستحصل على 0 يومًا ، إذا قمت بتشغيل هذا في المملكة المتحدة!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

طريقة أفضل لتنفيذ ذلك هي استخدام java.util.calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

هناك العديد من الطرق التي يمكنك من خلالها العثور على الفرق بين التواريخ والأوقات. واحدة من أبسط الطرق التي أعرفها هي:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

بيان الطباعة هو مجرد مثال - يمكنك تنسيقه ، بالطريقة التي تريدها.

نظرًا لأن جميع الإجابات هنا صحيحة ولكن استخدم Legacy Java أو Libs الطرف الثالث مثل Joda أو ما شابه ذلك ، فسوف أسقط طريقة أخرى باستخدام جديد Java.Time فصول في جافا 8 ثم. يرى تعليمي أوراكل.

يستخدم LocalDate و ChronoUnit:

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );

طرح التواريخ في أعمال المللي ثانية (كما هو موضح في منشور آخر) ، لكنك لديك لاستخدام HOW_OF_DAY وليس ساعة عند مسح الأجزاء الزمنية من تواريخك:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}

إذا كنت لا ترغب في استخدام jodatime أو ما شابه ، فمن المحتمل أن يكون الحل الأفضل هو:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

لا يكون عدد مرض التصلب العصبي المتعدد في اليوم هو نفسه دائمًا (بسبب التوفير في ضوء النهار والثواني القفزة) ، لكنه قريب جدًا ، وعلى الأقل انحرافات بسبب وقت توفير النهار على مدار فترات أطول. لذلك ، فإن التقسيم ثم التقريب سيعطي نتيجة صحيحة (على الأقل طالما أن التقويم المحلي المستخدم لا يحتوي على قفزات زمنية غريبة غير DST و LEAP Seconds).

لاحظ أن هذا لا يزال يفترض ذلك date1 و date2 يتم تعيينها على نفس الوقت من اليوم. لأوقات مختلفة من اليوم ، يجب عليك أولاً تحديد معنى "الفرق في التاريخ" ، كما أشار جون سكيت.

ألق نظرة على وقت جودا, ، وهو أمر محسن للتاريخ/الوقت واجهة برمجة تطبيقات لـ Java ويجب أن تعمل بشكل جيد مع Scala.

اسمحوا لي أن أظهر الفرق بين فاصل جودا والأيام:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 

إذا كنت بحاجة إلى سلسلة إرجاع منسقة مثل "2 أيام 03H 42M 07S" ، جرب هذا:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}

تحقق مثال هنا http://www.roseindia.net/java/beginners/datedifferent.shtmlيمنحك هذا المثال الفرق في الأيام والساعات والدقائق و Secs و Milli Sec :).

import java.util.Calendar;
import java.util.Date;

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        long milliseconds1 = calendar1.getTimeInMillis();
        long milliseconds2 = calendar2.getTimeInMillis();
        long diff = milliseconds2 - milliseconds1;
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);
        System.out.println("\nThe Date Different Example");
        System.out.println("Time in milliseconds: " + diff + " milliseconds.");
        System.out.println("Time in seconds: " + diffSeconds + " seconds.");
        System.out.println("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}

استخدم المنطقة الزمنية لـ GMT للحصول على مثيل للتقويم ، اضبط الوقت باستخدام طريقة SET لفئة التقويم. تحتوي المنطقة الزمنية لـ GMT على إزاحة 0 (ليست مهمة حقًا) وعلم التوفير في ضوء النهار على خطأ.

    final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 9);
    cal.set(Calendar.DAY_OF_MONTH, 29);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date startDate = cal.getTime();

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 12);
    cal.set(Calendar.DAY_OF_MONTH, 21);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date endDate = cal.getTime();

    System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));

يمكن أن يمنحك الرمز التالي الإخراج المطلوب:

String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);

String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);

System.out.println(date1.toEpochDay() - date.toEpochDay());
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   

ملاحظة: startdate و enddates هي -> java.util.date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start 
period.getStandardDays();

وتاريخ الانتهاء

على غرار الأيام ، يمكنك أيضًا الحصول على ساعات ودقائق وثواني

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;

أفضل شيء فعله هو

(Date1-Date2)/86 400 000 

هذا الرقم هو عدد ميلي ثانية في يوم.

يمنحك تاريخ تاريخ واحد الفرق في المللي ثانية.

جمع الإجابة في أ مزدوج عامل.

من المحتمل أن تكون هذه هي الطريقة الأكثر وضوحًا للقيام بذلك - ربما لأنني كنت أرمز في Java (مع مكتبات تاريخ ووقت معترف بها) لفترة من الوقت الآن ، لكن هذا الرمز يبدو "بسيطًا ولطيفًا" بالنسبة لي!

هل أنت سعيد بالنتيجة التي يتم إرجاعها بالمللي ثانية ، أم أن جزءًا من سؤالك تفضل إرجاعه بتنسيق بديل؟

عدم استخدام واجهة برمجة التطبيقات القياسية ، لا. يمكنك أن تدور حولها لفعل شيء مثل هذا:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

أو يمكنك استخدام جودا:

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);

فقط للإجابة على السؤال الأولي:

ضع الكود التالي في وظيفة مثل Long Getage () {}

Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;

return ageInMillis / MillisToYearsByDiv;

الأهم هنا هو العمل بأرقام طويلة عند الضرب والتقسيم. وبالطبع ، فإن الإزاحة التي تنطبق عليها Java في حساب التفاضل والتواريخ.

:)

منذ أن يتم وضع علامة على السؤال مع Scala ،

import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays

إليك حل Java 7 الصحيح في O (1) دون أي تبعيات.

public static int countDaysBetween(Date date1, Date date2) {

    Calendar c1 = removeTime(from(date1));
    Calendar c2 = removeTime(from(date2));

    if (c1.get(YEAR) == c2.get(YEAR)) {

        return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
    }
    // ensure c1 <= c2
    if (c1.get(YEAR) > c2.get(YEAR)) {
        Calendar c = c1;
        c1 = c2;
        c2 = c;
    }
    int y1 = c1.get(YEAR);
    int y2 = c2.get(YEAR);
    int d1 = c1.get(DAY_OF_YEAR);
    int d2 = c2.get(DAY_OF_YEAR);

    return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}

private static int countLeapYearsBetween(int y1, int y2) {

    if (y1 < 1 || y2 < 1) {
        throw new IllegalArgumentException("Year must be > 0.");
    }
    // ensure y1 <= y2
    if (y1 > y2) {
        int i = y1;
        y1 = y2;
        y2 = i;
    }

    int diff = 0;

    int firstDivisibleBy4 = y1;
    if (firstDivisibleBy4 % 4 != 0) {
        firstDivisibleBy4 += 4 - (y1 % 4);
    }
    diff = y2 - firstDivisibleBy4 - 1;
    int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;

    int firstDivisibleBy100 = y1;
    if (firstDivisibleBy100 % 100 != 0) {
        firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
    }
    diff = y2 - firstDivisibleBy100 - 1;
    int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;

    int firstDivisibleBy400 = y1;
    if (firstDivisibleBy400 % 400 != 0) {
        firstDivisibleBy400 += 400 - (y1 % 400);
    }
    diff = y2 - firstDivisibleBy400 - 1;
    int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;

    return divisibleBy4 - divisibleBy100 + divisibleBy400;
}


public static Calendar from(Date date) {

    Calendar c = Calendar.getInstance();
    c.setTime(date);

    return c;
}


public static Calendar removeTime(Calendar c) {

    c.set(HOUR_OF_DAY, 0);
    c.set(MINUTE, 0);
    c.set(SECOND, 0);
    c.set(MILLISECOND, 0);

    return c;
}

بعد الخوض في جميع الإجابات الأخرى ، للحفاظ على نوع تاريخ Java 7 ولكن كن أكثر دقة/قياسية مع نهج Java 8 Diff ،

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}

جرب هذا:

int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

يمكنك تحرير السلسلة في أساليب Parse () param.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top