网站地图 | RSS订阅 老铁博客 - 上海SEO优化|上海网站建设|蜘蛛池出租|站群代搭建
你的位置:首页 » 前端脚本 » 正文

simpledateformat,simpledateformat线程不安全

2020-2-26 15:15:37 | 作者:老铁SEO | 0个评论 | 人浏览

  publicclassSimpleDateFormatDemo{


  publicstaticvoidmain(String[]args)throwsParseException{


  //TODOAuto-generatedmethodstub


  SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss:SSS");//Date指定格式:yyyy-MM-ddHH:mm:ss:SSS


  Datedate=newDate();//创建一个date对象保存当前时间


  StringdateStr=simpleDateFormat.format(date);//format()方法将Date转换成指定格式的String


  System.out.println(dateStr);//2018-08-2415:37:47:033


  Stringstring="2018-8-2412:50:20:545";


  Datedate2=simpleDateFormat.parse(string);//调用parse()方法时注意传入的格式必须符合simpleDateFormat对象的格式,即"yyyy-MM-ddHH:mm:ss:SSS"否则会报错!!


  System.out.println(date2);//FriAug2412:50:20CST2018


  }


  }


  publicclassStringToDate


  {


  publicfinalstaticjava.sql.Datestring2Date(StringdateString)throwsjava.lang.Exception


  {


  DateFormatdateFormat;


  dateFormat=newSimpleDateFormat("yyyy-MM-ddkk:mm:ss",Locale.ENGLISH);


  dateFormat.setLenient(false);


  java.util.DatetimeDate=dateFormat.parse(dateString);//util类型


  java.sql.DatedateTime=newjava.sql.Date(timeDate.getTime());//sql类型


  returndateTime;


  }


  }


  date


  format


  simpledateformat线程不安全


  我们都知道jdk里面的SimpleDateFormat不是线程安全的,而commons-lang中的DateFormatUtils(或者说FastDateFormat)却是,非常快速描了一眼,发现里面也引用了SimpleDateFormat,那为什么它会线程安全?


  OK,仔细分析一下.


  1,假设我们调用如下方法


  publicstaticStringformat(Datedate,Stringpattern){


  returnformat(date,pattern,null,null);


  }


  间接调用


  publicstaticStringformat(Datedate,Stringpattern,TimeZonetimeZone,Localelocale){


  FastDateFormatdf=FastDateFormat.getInstance(pattern,timeZone,locale);


  returndf.format(date);


  }


  局部变量,暂时没什么问题.


  2,进入FastDateFormat


  publicstaticsynchronizedFastDateFormatgetInstance(Stringpattern,TimeZonetimeZone,Localelocale){


  FastDateFormatemptyFormat=newFastDateFormat(pattern,timeZone,locale);


  FastDateFormatformat=(FastDateFormat)cInstanceCache.get(emptyFormat);


  if(format==null){


  format=emptyFormat;


  format.init();//convertshellformatintousableone


  cInstanceCache.put(format,format);//thisisOK!


  }


  returnformat;


  }


  首先,这是个同步方法.


  其次,在构造方法中,只是对4个Final变量赋值.


  然后,如果找不到,则调用相应的init方法,这个方法里面也只是使用Final变量来对另外的两个transient变量赋值.


  再然后放到map中做缓存(提高速度)


  经过上面的操作,保证了只要传递的参数相同(pattern,timeZone,locale),获得的就是同一个实例,但是这个实例所拥有的共享变量是final的,没有其他的机会修改了,只读的share也没关系了.


  3,开始format


  同样,操作的也只是局部变量或者只读的final,transient变量,也没有问题.


  Ok,就这样达到了thread-safe.


  simpledateformat格式化日期


  importjava.util.Date;


  importjava.util.Locale;


  importjava.text.DateFormat;


  importjava.text.FieldPosition;


  /**


  *DateFormat的API测试程序


  */


  publicclassDateFormatTest{


  publicstaticvoidmain(String[]args){


  //只显示“时间”:调用getTimeInstance()函数


  testGetTimeInstance();


  //只显示“日期”:调用getDateInstance()函数


  testGetDateInstance();


  //显示“日期”+“时间”:调用getDateTimeInstance()函数


  testGetDateTimeInstance();


  //测试format()函数


  testFormat();


  }


  /**


  *测试DateFormat的getTimeInstance()函数


  *它共有3种重载形式:


  *(01)getTimeInstance()


  *(02)getTimeInstance(intstyle)


  *(03)getTimeInstance(intstyle,Localelocale)


  *


  *@authorskywang


  */


  privatestaticvoidtestGetTimeInstance(){


  Datedate=newDate();


  //Localelocale=newLocale("fr","FR");


  Localelocale=newLocale("zh","CN");


  //等价于DateFormat.getTimeInstance(DateFormat.MEDIUM);


  DateFormatshort0=DateFormat.getTimeInstance();


  //参数是:“时间的显示样式”


  DateFormatshort1=DateFormat.getTimeInstance(DateFormat.SHORT);


  DateFormatmedium1=DateFormat.getTimeInstance(DateFormat.MEDIUM);


  DateFormatlong1=DateFormat.getTimeInstance(DateFormat.LONG);


  DateFormatfull1=DateFormat.getTimeInstance(DateFormat.FULL);


  //参数是:“时间的显示样式”和“地区”


  DateFormatshort2=DateFormat.getTimeInstance(DateFormat.SHORT,locale);


  DateFormatmedium2=DateFormat.getTimeInstance(DateFormat.MEDIUM,locale);


  DateFormatlong2=DateFormat.getTimeInstance(DateFormat.LONG,locale);


  DateFormatfull2=DateFormat.getTimeInstance(DateFormat.FULL,locale);


  System.out.println("\n----getTimeInstance----\n"


  +"(1.0)EmptyParam:"+short0.format(date)+"\n"


  +"(2.1)OneParam(s):"+short1.format(date)+"\n"


  +"(2.2)OneParam(m):"+medium1.format(date)+"\n"


  +"(2.3)OneParam(l):"+long1.format(date)+"\n"


  +"(2.4)OneParam(f):"+full1.format(date)+"\n"


  +"(3.1)OneParam(s,l):"+short2.format(date)+"\n"


  +"(3.2)OneParam(m,l):"+medium2.format(date)+"\n"


  +"(3.3)OneParam(l,l):"+long2.format(date)+"\n"


  +"(3.4)OneParam(f,l):"+full2.format(date)+"\n"


  );


  }


  /**


  *测试DateFormat的getDateTimeInstance()函数


  *它共有3种重载形式:


  *(01)getDateInstance()


  *(02)getDateInstance(intstyle)


  *(03)getDateInstance(intstyle,Localelocale)


  */


  publicstaticvoidtestGetDateTimeInstance(){


  Datedate=newDate();


  Localelocale=newLocale("zh","CN");


  //等价于DateFormat.getDateTimeInstance(DateFormat.MEDIUM);


  DateFormatshort0=DateFormat.getDateTimeInstance();


  DateFormatshort1=DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);


  DateFormatmedium1=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);


  DateFormatlong1=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);


  DateFormatfull1=DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL);


  DateFormatshort2=DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT,locale);


  DateFormatmedium2=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM,locale);


  DateFormatlong2=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG,locale);


  DateFormatfull2=DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL,locale);


  System.out.println("\n----getDateTimeInstance----\n"


  +"(1.0)EmptyParam:"+short0.format(date)+"\n"


  +"(2.1)OneParam(s):"+short1.format(date)+"\n"


  +"(2.2)OneParam(m):"+medium1.format(date)+"\n"


  +"(2.3)OneParam(l):"+long1.format(date)+"\n"


  +"(2.4)OneParam(f):"+full1.format(date)+"\n"


  +"(3.1)OneParam(s,l):"+short2.format(date)+"\n"


  +"(3.2)OneParam(m,l):"+medium2.format(date)+"\n"


  +"(3.3)OneParam(l,l):"+long2.format(date)+"\n"


  +"(3.4)OneParam(f,l):"+full2.format(date)+"\n"


  );


  }


  /**


  *测试DateFormat的getDateInstance()函数


  *它共有3种重载形式:


  *(01)getDateTimeInstance()


  *(02)getDateTimeInstance(intdateStyle,inttimeStyle)


  *(03)getDateTimeInstance(intdateStyle,inttimeStyle,Localelocale)


  */


  publicstaticvoidtestGetDateInstance(){


  Datedate=newDate();


  //Localelocale=newLocale("en","US");


  Localelocale=newLocale("zh","CN");


  //等价于DateFormat.getDateInstance(DateFormat.MEDIUM);


  DateFormatshort0=DateFormat.getDateInstance();


  DateFormatshort1=DateFormat.getDateInstance(DateFormat.SHORT);


  DateFormatmedium1=DateFormat.getDateInstance(DateFormat.MEDIUM);


  DateFormatlong1=DateFormat.getDateInstance(DateFormat.LONG);


  DateFormatfull1=DateFormat.getDateInstance(DateFormat.FULL);


  DateFormatshort2=DateFormat.getDateInstance(DateFormat.SHORT,locale);


  DateFormatmedium2=DateFormat.getDateInstance(DateFormat.MEDIUM,locale);


  DateFormatlong2=DateFormat.getDateInstance(DateFormat.LONG,locale);


  DateFormatfull2=DateFormat.getDateInstance(DateFormat.FULL,locale);


  System.out.println("\n----getDateInstance----\n"


  +"(1.0)EmptyParam:"+short0.format(date)+"\n"


  +"(2.1)OneParam(s):"+short1.format(date)+"\n"


  +"(2.2)OneParam(m):"+medium1.format(date)+"\n"


  +"(2.3)OneParam(l):"+long1.format(date)+"\n"


  +"(2.4)OneParam(f):"+full1.format(date)+"\n"


  +"(3.1)OneParam(s,l):"+short2.format(date)+"\n"


  +"(3.2)OneParam(m,l):"+medium2.format(date)+"\n"


  +"(3.3)OneParam(l,l):"+long2.format(date)+"\n"


  +"(3.4)OneParam(f,l):"+full2.format(date)+"\n"


  );


  }


  /**


  *测试DateFormat的format()函数


  */


  publicstaticvoidtestFormat(){


  Datedate=newDate();


  StringBuffersb=newStringBuffer();


  FieldPositionfield=newFieldPosition(DateFormat.YEAR_FIELD);


  DateFormatformat=DateFormat.getDateTimeInstance();


  sb=format.format(date,sb,field);


  System.out.println("\ntestFormat");


  System.out.printf("sb=%s\n",sb);


  }


  }


  simpledateformat格式


  newDate()得到的是系统当前时间


  SimpleDateFormat从java.text.DateFormat继承了format这个方法,具体方法签名如下:


  format


  publicfinalStringformat(Datedate)


  将一个Date格式化为日期/时间字符串。


  字母日期或时间元素表示示例


  GEra标志符TextAD


  y年Year1996;96


  M年中的月份MonthJuly;Jul;07


  w年中的周数Number27


  W月份中的周数Number2


  D年中的天数Number189


  d月份中的天数Number10


  F月份中的星期Number2


  E星期中的天数TextTuesday;Tue


  aAm/pm标记TextPM


  H一天中的小时数(0-23)Number0


  k一天中的小时数(1-24)Number24


  Kam/pm中的小时数(0-11)Number0


  ham/pm中的小时数(1-12)Number12


  m小时中的分钟数Number30


  s分钟中的秒数Number55


  S毫秒数Number978


  z时区GeneraltimezonePacificStandardTime;PST;GMT-08:00


  Z时区RFC822timezone-0800


  simpledateformat用法


  newDate()得到的是系统当前时间


  SimpleDateFormat从java.text.DateFormat继承了format这个方法,具体方法签名如下:


  format


  publicfinalStringformat(Datedate)


  将一个Date格式化为日期/时间字符串。


  字母日期或时间元素表示示例


  GEra标志符TextAD


  y年Year1996;96


  M年中的月份MonthJuly;Jul;07


  w年中的周数Number27


  W月份中的周数Number2


  D年中的天数Number189


  d月份中的天数Number10


  F月份中的星期Number2


  E星期中的天数TextTuesday;Tue


  aAm/pm标记TextPM


  H一天中的小时数(0-23)Number0


  k一天中的小时数(1-24)Number24


  Kam/pm中的小时数(0-11)Number0


  ham/pm中的小时数(1-12)Number12


  m小时中的分钟数Number30


  s分钟中的秒数Number55


  S毫秒数Number978


  z时区GeneraltimezonePacificStandardTime;PST;GMT-08:00


  Z时区RFC822timezone-0800

  • 本文来自: 老铁博客,转载请保留出处!欢迎发表您的评论
  • 相关标签:
  • 已有0位网友发表了一针见血的评论,你还等什么?

    必填

    选填

    记住我,下次回复时不用重新输入个人信息

    必填,不填不让过哦,嘻嘻。

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    相关推荐