تحليل هذا النوع من تنسيق التاريخ في جافا؟ [مكرر

StackOverflow https://stackoverflow.com/questions/4013681

  •  26-09-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

ماذا ستكون أسهل طريقة لتحليل تنسيق التاريخ هذا أدناه في جافا؟:

2010-09-18T10:00:00.000+01:00

قرأت API DateFormat في Java ولم أتمكن من العثور على طريقة تأخذ سلسلة أو حتى هذا النوع من تنسيق التاريخ باعتباره paremeter لتحليله؟ عندما أعني بالحاجز ، أعني أنني أريد استخراج "التاريخ (الشهر والعام)" و "الوقت" و "Timezone" إلى كائنات سلسلة منفصلة.

شكرا لك مقدما

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

المحلول

إجابة أخرى ، حيث يبدو أنك تركز على مجرد تمزيق String بصرف النظر (ليست فكرة جيدة ، IMHO.) لنفترض أن السلسلة صالحة ISO8601. هل يمكنك أن تفترض أنه سوف دائماً كن في النموذج الذي تستشهد به ، أم أنه صالح 8601؟ إذا كان الأخير ، عليك التعامل مع مجموعة من السيناريوهات هؤلاء الرجال فعلوا.

regex توصلوا إليها للتحقق من صحة 8601 بدائل هي:

^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])
 (-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])
 ((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?
 ([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$ 

إن معرفة كيفية إثارة مجموعات الالتقاط الصحيحة يجعلني أرتدي. ومع ذلك ، فإن ما يلي سيعمل لحالتك المحددة:

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Regex8601
{
  static final Pattern r8601 = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})T((\\d{2}):"+
                               "(\\d{2}):(\\d{2})\\.(\\d{3}))((\\+|-)(\\d{2}):(\\d{2}))");


  //2010-09-18T10:00:00.000+01:00

  public static void main(String[] args)
  {
    String thisdate = "2010-09-18T10:00:00.000+01:00";
    Matcher m = r8601.matcher(thisdate);
    if (m.lookingAt()) {
      System.out.println("Year: "+m.group(1));
      System.out.println("Month: "+m.group(2));
      System.out.println("Day: "+m.group(3));
      System.out.println("Time: "+m.group(4));
      System.out.println("Timezone: "+m.group(9));
    } else {
      System.out.println("no match");
    }
  }
}

نصائح أخرى

إذا كنت تفعل أي شيء غير تافهة مع التواريخ والأوقات ، أوصي باستخدام jodatime. يرى هذه المناقشة واسعة النطاق, ، بما فيها ISO8601. أنظر أيضا "هل يجب أن أستخدم البيانات/الوقت الأصلي ...".

إليك مثال رمز المقتطف ، مأخوذ من هذا المثال, ، إذا كنت تريد استخدام JDK SimpleDateFormat.

// 2004-06-14T19:GMT20:30Z
// 2004-06-20T06:GMT22:01Z

// http://www.cl.cam.ac.uk/~mgk25/iso-time.html
//    
// http://www.intertwingly.net/wiki/pie/DateTime
//
// http://www.w3.org/TR/NOTE-datetime
//
// Different standards may need different levels of granularity in the date and
// time, so this profile defines six levels. Standards that reference this
// profile should specify one or more of these granularities. If a given
// standard allows more than one granularity, it should specify the meaning of
// the dates and times with reduced precision, for example, the result of
// comparing two dates with different precisions.

// The formats are as follows. Exactly the components shown here must be
// present, with exactly this punctuation. Note that the "T" appears literally
// in the string, to indicate the beginning of the time element, as specified in
// ISO 8601.

//    Year:
//       YYYY (eg 1997)
//    Year and month:
//       YYYY-MM (eg 1997-07)
//    Complete date:
//       YYYY-MM-DD (eg 1997-07-16)
//    Complete date plus hours and minutes:
//       YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
//    Complete date plus hours, minutes and seconds:
//       YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
//    Complete date plus hours, minutes, seconds and a decimal fraction of a
// second
//       YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)

// where:

//      YYYY = four-digit year
//      MM   = two-digit month (01=January, etc.)
//      DD   = two-digit day of month (01 through 31)
//      hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
//      mm   = two digits of minute (00 through 59)
//      ss   = two digits of second (00 through 59)
//      s    = one or more digits representing a decimal fraction of a second
//      TZD  = time zone designator (Z or +hh:mm or -hh:mm)
public static Date parse( String input ) throws java.text.ParseException 
{
  //NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
  //things a bit.  Before we go on we have to repair this.
  SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );

  //this is zero time so we need to add that TZ indicator for 
  if ( input.endsWith( "Z" ) ) {
    input = input.substring( 0, input.length() - 1) + "GMT-00:00";
  } else {
    int inset = 6;

    String s0 = input.substring( 0, input.length() - inset );
    String s1 = input.substring( input.length() - inset, input.length() );    

    input = s0 + "GMT" + s1;
  }

  return df.parse( input );        
}

هذا التاريخ في تنسيق ISO 8601. هنا رابط إلى محلل خاص بهذا التنسيق الذي يستخدم java simpledateformat parsing واجهات برمجة التطبيقات داخليا.

يجب أن تستخدم SimpleDateFormat,

ابحث عن أمثلة هنا و هنا للبدء.

يمكنك استخدام javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation) (مستندات API). يمنحك XMLGregorianCalendar العائد إمكانية الوصول إلى جميع الحقول المنفصلة.

يستخدم SimpleDateFormat, ، مع النمط كما yyy-MM-dd'T'HH:mm:ss.SSSZ


تحديث لن يعمل SimpleDateFormat مع تنسيق تاريخ ISO 8601. بدلا من الاستخدام ، jodatime في حين أن. أنه يوفر علم الأيزوكرونات هذا يتوافق مع ISO 8601.

يمكن العثور على مثال موجز على لذا.

أسهل حل هو:

Date date = null;
SimpleDateFormat isoFormatWithMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
try {
    date = isoFormatWithMillis.parse("2010-09-18T10:00:00.000+01:00");
} catch (ParseException e) {
    e.printStackTrace();
}
System.out.println(date);

هذا سوف يطبع Sat Sep 18 11:00:00 CEST 2010.

إذا كنت تستخدم Java 7 أو قبل ذلك ، يمكنك الرجوع إلى هذا بريد.

إذا كنت تستخدم Java 8 يمكنك القيام بذلك:

    DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
    TemporalAccessor accessor = timeFormatter.parse("2015-10-27T16:22:27.605-07:00");

    Date date = Date.from(Instant.from(accessor));
    System.out.println(date);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top