java شرح - كيفية حفظ واسترجاع التاريخ في SharedPreferences




android example (4)

أحتاج إلى حفظ بعض التواريخ في SharedPreferences في Android واستردادها. أقوم AlarmManager تطبيق تذكير باستخدام AlarmManager إلى حفظ قائمة التواريخ المستقبلية. يجب أن تكون قادرة على استرداد كما ميلي ثانية. أولاً فكرت في حساب الوقت بين الوقت الحالي والوقت المستقبلي وتخزينه في تفضيلات مشتركة. لكن هذه الطريقة لا تعمل لأنني أحتاج إلى استخدامها في AlarmManager .


Answers

لحفظ تاريخ دقيق وتحميله ، يمكنك استخدام التمثيل long (العدد) لكائن Date .

مثال:

//getting the current time in milliseconds, and creating a Date object from it:
Date date = new Date(System.currentTimeMillis()); //or simply new Date();

//converting it back to a milliseconds representation:
long millis = date.getTime();

يمكنك استخدام هذا لحفظ أو استرداد بيانات Date / Time من SharedPreferences مثل هذا

حفظ:

SharedPreferences prefs = ...;
prefs.edit().putLong("time", date.getTime()).apply();

اقرأها مرة أخرى:

Date myDate = new Date(prefs.getLong("time", 0));

تصحيح

إذا كنت ترغب في تخزين إضافة TimeZone ، فيمكنك كتابة بعض الطرق المساعدة لهذا الغرض ، شيء من هذا القبيل (لم أختبرها ، ولا تتردد في تصحيحها ، إذا كان هناك خطأ ما):

public static Date getDate(final SharedPreferences prefs, final String key, final Date defValue) {
    if (!prefs.contains(key + "_value") || !prefs.contains(key + "_zone")) {
        return defValue;
    }
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(prefs.getLong(key + "_value", 0));
    calendar.setTimeZone(TimeZone.getTimeZone(prefs.getString(key + "_zone", TimeZone.getDefault().getID())));
    return calendar.getTime();
}

public static void putDate(final SharedPreferences prefs, final String key, final Date date, final TimeZone zone) {
    prefs.edit().putLong(key + "_value", date.getTime()).apply();
    prefs.edit().putString(key + "_zone", zone.getID()).apply();
}

ليرة تركية، والدكتور

يستخدم الأسلوب الحديث فصول java.time وسلاسل ISO 8601 .

قراءة.

Instant                             // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochMilli( 
    Long.getLong( incomingText )  
)                                   // Returns a `Instant` object.
.atZone(                            // Adjust from UTC to some time zone. Same moment, same point on the timeline, different wall-clock time.
    ZoneId.of( "Europe/Paris" ) 
)                                   // Returns a `ZonedDateTime` object.

جاري الكتابة.

ZonedDateTime
.of(
    LocalDate.of( 2018 , Month.JANUARY , 23 ) ,
    LocalTime.of( 15 , 35 ) ,
    ZoneId.of( "Europe/Paris" ) 
)                                   // Returns a `ZonedDateTime` object.
.toInstant()                        // Returns an `Instant`. Adjust from a time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
.toEpochMilli()                     // Returns a `long` integer number primitive. Any microseconds or nanoseconds are ignored, of course.

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

java.util.Date d = java.util.Date.from( instant ) ;

... و ...

Instant instant = d.toInstant() ;

java.time

تم استبدال فصول التاريخ القديم المزعجة بفصول java.time .

للحظة في التوقيت العالمي المتفق عليه (UTC) ، باستخدام دقة النانو ثانية ، استخدم البحث Instant .

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

لا تريد سوى ميلي ثانية واحدة لاحتياجاتك ، لذلك اقتطع أي جزء من الثانية من النانو والثانية.

Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;

لتحديد لحظة حسب التاريخ والوقت من اليوم يتطلب منطقة زمنية. تعد المنطقة الزمنية أمرًا مهمًا في تحديد تاريخ. في أي لحظة معينة ، يختلف التاريخ في جميع أنحاء العالم حسب المنطقة. على سبيل المثال ، بعد دقائق قليلة من منتصف الليل في باريس ، يعد يوم فرنسا يومًا جديدًا بينما لا يزال "بالأمس" في مونتريال كيبيك .

في حالة عدم تحديد منطقة زمنية ، يطبق JVM ضمنيًا المنطقة الزمنية الافتراضية الحالية. قد يتغير هذا الإعداد الافتراضي في أي وقت أثناء وقت التشغيل (!) ، لذلك قد تختلف نتائجك. من الأفضل تحديد منطقتك الزمنية المرغوبة / المتوقعة بوضوح كوسيطة.

حدد اسم منطقة زمنية مناسبة بتنسيق continent/region ، مثل America/Montreal أو Africa/Casablanca أو Pacific/Auckland . لا تستخدم اختصار الحروف من 3-4 أحرف مثل EST أو IST لأنها ليست مناطق زمنية حقيقية وليست قياسية ولا فريدة (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

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

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

أو تحديد موعد. يمكنك تعيين الشهر برقم ، مع ترقيم رقم 1-12 لشهر يناير وديسمبر.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

أو ، على نحو أفضل ، استخدم كائنات التعداد الشهرية محددة مسبقًا ، واحدة لكل شهر من السنة. تلميح: استخدم كائنات Month هذه عبر قاعدة بياناتك بدلاً من مجرد رقم صحيح لجعل الشفرة الخاصة بك أكثر توثيقًا ذاتيًا ، وضمان القيم الصحيحة ، وتوفير type-safety .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

مع الجمع بين الوقت من اليوم ، LocalTime .

LocalTime lt = LocalTime.of( 14 , 0 ) ;

التفاف كل ذلك معاً ككائن ZonedDateTime .

ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

اضبط على التوقيت العالمي المنسق (UTC) عن طريق استخراج Instant .

Instant instant = zdt.toInstant() ;

قم باستخراج عدد المللي ثانية المرغوب فيه منذ مرجع الحقبة الأولى من عام 1970 بالتوقيت العالمي المنسق. مرة أخرى ، كن على دراية بأنه سيتم تجاهل أي وحدات مايكرو / نانوية في محادثتك Instant عند استخراج المللي ثانية.

long milliseconds = instant.toEpochMilli() ;  // Be aware of potential data loss, ignoring any microseconds or nanoseconds. 

اقرأ تلك المللي ثانية مرة أخرى من التخزين كنص باستخدام الفئة Long .

long milliseconds = Long.getLong( incomingText ) ;
Instant instant = Instant.ofEpochMilli( milliseconds ) ;

لرؤية تلك اللحظة من خلال عدسة وقت ساعة الحائط التي يستخدمها الأشخاص في منطقة معينة (منطقة زمنية) ، قم بتطبيق ZoneId للحصول على ZonedDateTime .

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

لإنشاء نص يمثل تلك القيمة ، استخدم DateTimeFormatter.ofLocalizedDateTime تلقائيًا.

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

String output = instant.toString() ; 

2018-10-05T20: 28: 48.584Z

Instant instant = Instant.parse( 2018-10-05T20:28:48.584Z ) ;

حول java.time

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

ينصح مشروع java.time Joda-Time ، الآن في وضع الصيانة ، java.time فصول java.time .

لمعرفة المزيد ، راجع Oracle Tutorial . وابحث في عن العديد من الأمثلة والتفسيرات. المواصفات JSR 310 .

يمكنك تبادل كائنات java.time مباشرة مع قاعدة البيانات الخاصة بك. استخدم برنامج تشغيل JDBC متوافق مع JDBC 4.2 أو أحدث. لا حاجة للسلاسل ، لا حاجة لفصول java.sql.* .

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

  • Java SE 8 و Java SE 9 و Java SE 10 و Java SE 11 والإصدارات الأحدث - جزء من واجهة برمجة تطبيقات Java القياسية مع تطبيق مجمع.
    • يضيف Java 9 بعض الميزات الطفيفة والإصلاحات.
  • Java SE 6 و Java SE 7
    • يتم إعادة نقل معظم وظائف java.time إلى Java 6 & 7 في ThreeTen-Backport .
  • Android
    • الإصدارات الأحدث من تطبيقات حزمة أندرويد لفئات java.time .
    • بالنسبة ThreeTenABP Android السابق (<26) ، فإن مشروع ThreeTen-Backport يتكيف مع ThreeTen-Backport (المذكورة أعلاه). انظر كيفية استخدام ThreeTenABP ....

يمتد مشروع ThreeTen-Extra java.time مع فصول إضافية. هذا المشروع هو أرضية تثبت الإضافات المستقبلية المحتملة إلى java.time. قد تجد بعض الفئات المفيدة هنا مثل Interval و YearWeek و YearQuarter more .


انت تستطيع فعل ذالك:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.US);

لحفظ التاريخ:

preferences .edit().putString("mydate", sdf.format(date)).apply();

لأسترجاع:

try{
    Date date = sdf.parse(preferences.getString("myDate", "defaultValue"));
    } catch (ParseException e) {
                e.printStackTrace();
                               }

آمل أن يساعد.


إذا كنت تحتاج إلى تنسيق getMonth + 1 بسرعة باستخدام جافا سكريبت عادي ، استخدم getDate ، getMonth + 1 ، getFullYear ، getHours و getMinutes :

var d = new Date();

var datestring = d.getDate()  + "-" + (d.getMonth()+1) + "-" + d.getFullYear() + " " +
d.getHours() + ":" + d.getMinutes();

// 16-5-2015 9:50

أو إذا كنت تريد أن تكون مبطنًا بأصفار:

var datestring = ("0" + d.getDate()).slice(-2) + "-" + ("0"+(d.getMonth()+1)).slice(-2) + "-" +
    d.getFullYear() + " " + ("0" + d.getHours()).slice(-2) + ":" + ("0" + d.getMinutes()).slice(-2);

// 16-05-2015 09:50




java android date calendar sharedpreferences