??xml version="1.0" encoding="utf-8" standalone="yes"?>
众所周知Q在E序开发中Q难免会遇到需要匹配、查找、替换、判断字W串的情况发生,而这些情冉|时又比较复杂Q如果用U编码方式解冻I往往会浪费程序员的时间及_֊。因此,学习及用正则表辑ּQ便成了解决q一矛盾的主要手Dc?br />
大家都知道,正则表达式是一U可以用于模式匹配和替换的规范,一个正则表辑ּ是由普通的字符Q例如字Wa到zQ以及特D字W(元字W)l成的文字模式,它用以描q在查找文字M时待匚w的一个或多个字符丌Ӏ正则表辑ּ作ؓ一个模板,某个字W模式与所搜烦的字W串q行匚w?br />
自从jdk1.4推出java.util.regex包,׃ؓ我们提供了很好的JAVA正则表达式应用^台?br />
因ؓ正则表达式是一个很庞杂的体p,所以我仅例举些入门的概念,更多的请参阅相关书籍及自行摸索?
\\ 反斜?br />
\t 间隔 ('\u0009')
\n 换行 ('\u000A')
\r 回R ('\u000D')
\d 数字 {h于[0-9]
\D 非数?{h于[^0-9]
\s I白W号 [\t\n\x0B\f\r]
\S 非空白符?[^\t\n\x0B\f\r]
\w 单独字符 [a-zA-Z_0-9]
\W 非单独字W?[^a-zA-Z_0-9]
\f 换页W?br />
\e Escape
\b 一个单词的边界
\B 一个非单词的边?br />
\G 前一个匹配的l束
^为限制开?br />
^java 条g限制ZJava为开头字W?br />
$为限制结?br />
java$ 条g限制Zjava为结֭W?br />
.为限制一个Q意字W?br />
java.. 条g限制为java后除换行外Q意两个字W?br />
加入特定限制条g「[]?br />
[a-z] 条g限制在小写a to z范围中一个字W?br />
[A-Z] 条g限制在大写A to Z范围中一个字W?br />
[a-zA-Z] 条g限制在小写a to z或大写A to Z范围中一个字W?br />
[0-9] 条g限制在小? to 9范围中一个字W?br />
[0-9a-z] 条g限制在小? to 9或a to z范围中一个字W?br />
[0-9[a-z]] 条g限制在小? to 9或a to z范围中一个字W?交集)
[]中加入^后加再次限制条g「[^]?br />
[^a-z] 条g限制在非写a to z范围中一个字W?br />
[^A-Z] 条g限制在非大写A to Z范围中一个字W?br />
[^a-zA-Z] 条g限制在非写a to z或大写A to Z范围中一个字W?br />
[^0-9] 条g限制在非写0 to 9范围中一个字W?br />
[^0-9a-z] 条g限制在非写0 to 9或a to z范围中一个字W?br />
[^0-9[a-z]] 条g限制在非写0 to 9或a to z范围中一个字W?交集)
在限制条件ؓ特定字符出现0ơ以上时Q可以用??br />
J* 0个以上J
.* 0个以上Q意字W?br />
J.*D J与D之间0个以上Q意字W?br />
在限制条件ؓ特定字符出现1ơ以上时Q可以用??br />
J+ 1个以上J
.+ 1个以上Q意字W?br />
J.+D J与D之间1个以上Q意字W?br />
在限制条件ؓ特定字符出现??ơ以上时Q可以用??br />
JA? J或者JA出现
限制l出现指定次数字W「{a}?br />
J{2} JJ
J{3} JJJ
文字a个以上,q且「{a,}?br />
J{3,} JJJ,JJJJ,JJJJJ,???(3ơ以上Jq存)
文字个以上,b个以下「{a,b}?br />
J{3,5} JJJ或JJJJ或JJJJJ
两者取一「|?br />
J|A J或A
Java|Hello Java或Hello
?)」中规定一个组合类?br />
比如Q我查询<a href=\"index.html\">index</a>?lt;a href></a>间的数据Q可写作<a.*href=\".*\">(.+?)</a>
在用Pattern.compile函数Ӟ可以加入控制正则表达式的匚w行ؓ的参敎ͼ
Pattern Pattern.compile(String regex, int flag)
flag的取D围如下:
Pattern.CANON_EQ 当且仅当两个字符?正规分解(canonical decomposition)"都完全相同的情况下,才认定匹配。比如用了这个标志之后,表达?a\u030A"会匹??"。默认情况下Q不考虑"规范相等?canonical equivalence)"?br />
Pattern.CASE_INSENSITIVE(?i) 默认情况下,大小写不明感的匹配只适用于US-ASCII字符集。这个标志能让表辑ּ忽略大小写进行匹配。要惛_Unicode字符q行大小不明感的匚wQ只要将UNICODE_CASE与这个标志合hp了?br />
Pattern.COMMENTS(?x) 在这U模式下Q匹配时会忽?正则表达式里?I格字符(译者注Q不是指表达式里?\\s"Q而是指表辑ּ里的I格QtabQ回车之c?。注释从#开始,一直到q行l束。可以通过嵌入式的标志来启用Unix行模式?br />
Pattern.DOTALL(?s) 在这U模式下Q表辑ּ'.'可以匚wL字符Q包括表CZ行的l束W。默认情况下Q表辑ּ'.'不匹配行的结束符?br />
Pattern.MULTILINE
(?m) 在这U模式下Q?^'?$'分别匚w一行的开始和l束。此外,'^'仍然匚w字符串的开始,'$'也匹配字W串的结束。默认情况下Q这两个表达式仅仅匹配字W串的开始和l束?br />
Pattern.UNICODE_CASE
(?u) 在这个模式下Q如果你q启用了CASE_INSENSITIVE标志Q那么它会对Unicode字符q行大小写不明感的匹配。默认情况下Q大写不敏感的匚w只适用于US-ASCII字符集?br />
Pattern.UNIX_LINES(?d) 在这个模式下Q只?\n'才被认作一行的中止Qƈ且与'.'Q?^'Q以?$'q行匚w?br />
抛开I泛的概念,下面写出几个单的Java正则用例Q?br />
◆比如,在字W串包含验证?br />
//查找以Java开?Ll尾的字W串
Pattern pattern = Pattern.compile("^Java.*");
Matcher matcher = pattern.matcher("Java不是?);
boolean b= matcher.matches();
//当条件满xQ将q回trueQ否则返回false
System.out.println(b);
◆以多条件分割字W串?br />
Pattern pattern = Pattern.compile("[, |]+");
String[] strs = pattern.split("Java Hello World Java,Hello,,World|Sun");
for (int i=0;i<strs.length;i++) {
System.out.println(strs[i]);
}
◆文字替换(首次出现字符Q?br />
Pattern pattern = Pattern.compile("正则表达?);
Matcher matcher = pattern.matcher("正则表达?Hello World,正则表达?Hello World");
//替换W一个符合正则的数据
System.out.println(matcher.replaceFirst("Java"));
◆文字替换(全部Q?br />
Pattern pattern = Pattern.compile("正则表达?);
Matcher matcher = pattern.matcher("正则表达?Hello World,正则表达?Hello World");
//替换W一个符合正则的数据
System.out.println(matcher.replaceAll("Java"));
◆文字替换(|换字符Q?br />
Pattern pattern = Pattern.compile("正则表达?);
Matcher matcher = pattern.matcher("正则表达?Hello World,正则表达?Hello World ");
StringBuffer sbr = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sbr, "Java");
}
matcher.appendTail(sbr);
System.out.println(sbr.toString());
◆验证是否ؓ邮箱地址
String str="ceponline@yahoo.com.cn";
Pattern pattern = Pattern.compile("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+",Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.matches());
◆去除html标记
Pattern pattern = Pattern.compile("<.+?>", Pattern.DOTALL);
Matcher matcher = pattern.matcher("<a href=\"index.html\">主页</a>");
String string = matcher.replaceAll("");
System.out.println(string);
◆查找html中对应条件字W串
Pattern pattern = Pattern.compile("href=\"(.+?)\"");
Matcher matcher = pattern.matcher("<a href=\"index.html\">主页</a>");
if(matcher.find())
System.out.println(matcher.group(1));
}
◆截取http://地址
//截取url
Pattern pattern = Pattern.compile("(http://|https://){1}[\\w\\.\\-/:]+");
Matcher matcher = pattern.matcher("dsdsds<http://dsds//gfgffdfd>fdf");
StringBuffer buffer = new StringBuffer();
while(matcher.find()){
buffer.append(matcher.group());
buffer.append("\r\n");
System.out.println(buffer.toString());
}
◆替换指定{}中文?br />
String str = "Java目前的发展史是由{0}q?{1}q?;
String[][] object={new String[]{"\\{0\\}","1995"},new String[]{"\\{1\\}","2007"}};
System.out.println(replace(str,object));
public static String replace(final String sourceString,Object[] object) {
String temp=sourceString;
for(int i=0;i<object.length;i++){
String[] result=(String[])object[i];
Pattern pattern = Pattern.compile(result[0]);
Matcher matcher = pattern.matcher(temp);
temp=matcher.replaceAll(result[1]);
}
return temp;
}
◆以正则条g查询指定目录下文?br />
//用于~存文g列表
private ArrayList files = new ArrayList();
//用于承蝲文g路径
private String _path;
//用于承蝲未合q的正则公式
private String _regexp;
class MyFileFilter implements FileFilter {
/**
* 匚w文g名称
*/
public boolean accept(File file) {
try {
Pattern pattern = Pattern.compile(_regexp);
Matcher match = pattern.matcher(file.getName());
return match.matches();
} catch (Exception e) {
return true;
}
}
}
/**
* 解析输入?br />
* @param inputs
*/
FilesAnalyze (String path,String regexp){
getFileName(path,regexp);
}
/**
* 分析文g名ƈ加入files
* @param input
*/
private void getFileName(String path,String regexp) {
//目录
_path=path;
_regexp=regexp;
File directory = new File(_path);
File[] filesFile = directory.listFiles(new MyFileFilter());
if (filesFile == null) return;
for (int j = 0; j < filesFile.length; j++) {
files.add(filesFile[j]);
}
return;
}
/**
* 昄输出信息
* @param out
*/
public void print (PrintStream out) {
Iterator elements = files.iterator();
while (elements.hasNext()) {
File file=(File) elements.next();
out.println(file.getPath());
}
}
public static void output(String path,String regexp) {
FilesAnalyze fileGroup1 = new FilesAnalyze(path,regexp);
fileGroup1.print(System.out);
}
public static void main (String[] args) {
output("C:\\","[A-z|.]*");
}
Java正则的功用还有很多,事实上只要是字符处理Q就没有正则做不到的事情存在。(当然Q正则解释时较耗时间就是了|||……Q?br />
JDT实际上是Java代码构徏成一个基于DOMl构的抽象语法树ASTQAbstract Syntax Tree Q。代码中的每个部分都对应一个ASTNodeQ许多的ASTNode构成了q个抽象的语法树。Java Class一般对应Compilation Unit nodeQ该节点也是AST树上的顶炏V创Z个AST如下Q?/font>
其中createASTQ当parse需要较长时间时Q可以采用createAST(new NullProgressMonitor())Q否则直接传null卛_?/font>
recordModifications()用于记录节点的变动,比如修改、删除等Q当需要对AST树进行变动操作时Q必要预先调用q个Ҏ?/font>
比较重要的是Q一个AST树上的所有节点必都属于该AST。不允许直接其他AST树上的节Ҏ加该AST树上。否则会抛出java.lang.IllegalArgumentException异常。须使用ASTNode.copySubtree(AST target, ASTNode node)q回一个目标树的深度拷贝,才能q行d操作。例?
// package astexplorer;List 2 生成Importjava 代码
- PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
- unit.setPackage(packageDeclaration);
- packageDeclaration.setName(ast.newSimpleName("astexplorer"));
// import org.eclipse.swt.SWT;List 3 生成Class Declaration
// import org.eclipse.swt.events.*;
// import org.eclipse.swt.graphics.*;
// import org.eclipse.swt.layout.*;
// import org.eclipse.swt.widgets.*;java 代码
- for (int i = 0; i < IMPORTS.length; ++i) {
- ImportDeclaration importDeclaration = ast.newImportDeclaration();
- importDeclaration.setName(ast.newName(getSimpleNames(IMPORTS[i])));
- if (IMPORTS[i].indexOf("*") > 0)
- importDeclaration.setOnDemand(true);
- else
- importDeclaration.setOnDemand(false);
- unit.imports().add(importDeclaration);
- }
// public class SampleComposite extends Composite
java 代码
- TypeDeclaration classType = ast.newTypeDeclaration();
- classType.setInterface(false);
- classType.setModifiers(Modifier.PUBLIC);
- classType.setName(ast.newSimpleName("SampleComposite"));
- classType.setSuperclass(ast.newSimpleName("Composite"));
- unit.types().add(classType);
List 4 生成Constructor Declaration
// public SampleComposite(Composite parent,int style){}
java 代码
- MethodDeclaration methodConstructor = ast.newMethodDeclaration();
- methodConstructor.setConstructor(true);
- methodConstructor.setModifiers(Modifier.PUBLIC);
- methodConstructor.setName(ast.newSimpleName("SampleComposite"));
- classType.bodyDeclarations().add(methodConstructor);
- // constructor parameters
- SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration();
- variableDeclaration.setModifiers(Modifier.NONE);
- variableDeclaration.setType(ast.newSimpleType(ast.newSimpleName("Composite")));
- variableDeclaration.setName(ast.newSimpleName("parent"));
- methodConstructor.parameters().add(variableDeclaration);
- variableDeclaration = ast.newSingleVariableDeclaration();
- variableDeclaration.setModifiers(Modifier.NONE);
- variableDeclaration.setType(ast.newPrimitiveType(PrimitiveType.INT));
- variableDeclaration.setName(ast.newSimpleName("style"));
- methodConstructor.parameters().add(variableDeclaration);
- Block constructorBlock = ast.newBlock();
- methodConstructor.setBody(constructorBlock);
List 5 生成Spuer Invocation
// super(parent,style)
java 代码
- SuperConstructorInvocation superConstructorInvocation = ast.newSuperConstructorInvocation();
- constructorBlock.statements().add(superConstructorInvocation);
- Expression exp = ast.newSimpleName("parent");
- superConstructorInvocation.arguments().add(exp);
- superConstructorInvocation.arguments().add(ast.newSimpleName("style"));
List 6 生成ClassInstanceCreation
// GridLayout gridLayout = new GridLayout();
java 代码
- VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment();
- vdf.setName(ast.newSimpleName("gridLayout"));
- ClassInstanceCreation cc = ast.newClassInstanceCreation();
- cc.setName(ast.newSimpleName("GridLayout"));
- vdf.setInitializer(cc);
- VariableDeclarationStatement vds = ast.newVariableDeclarationStatement(vdf);
- vds.setType(ast.newSimpleType(ast.newSimpleName("GridLayout")));
- constructBlock.statements().add(vds);
// Label label = new Label(this,SWT.NONE);
java 代码
- VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment();
- vdf.setName(ast.newSimpleName("label"));
- cc = ast.newClassInstanceCreation();
- cc.setName(ast.newSimpleName("Label"));
- cc.arguments().add(ast.newThisExpression());
- cc.arguments().add(ast.newName(getSimpleNames("SWT.NONE")));
- vdf.setInitializer(cc);
- VariableDeclarationStatement vds = ast.newVariableDeclarationStatement(vdf);
- vds.setType(ast.newSimpleType(ast.newSimpleName("Label")));
- constructBlock.statements().add(vds);
List 7生成MethodInvocation
// setLayout(gridLayout);
java 代码
- MethodInvocation mi = ast.newMethodInvocation();
- mi.setName(ast.newSimpleName("setLayout"));
- mi.arguments().add(ast.newSimpleName("gridLayout"));
- constructorBlock.statements().add(ast.newExpressionStatement(mi));
// label.setText("Press the button to close:");
java 代码
- mi = ast.newMethodInvocation();
- mi.setExpression(ast.newSimpleName("label"));
- mi.setName(ast.newSimpleName("setText"));
- StringLiteral sl = ast.newStringLiteral();
- sl.setLiteralValue("Press the button to close:");
- mi.arguments().add(sl);
- constructorBlock.statements().add(ast.newExpressionStatement(mi));
// label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
java 代码
- mi = ast.newMethodInvocation();
- mi.setExpression(ast.newSimpleName("label"));
- mi.setName(ast.newSimpleName("setLayoutData"));
- cc = ast.newClassInstanceCreation();
- cc.setName(ast.newSimpleName("GridData"));
- cc.arguments().add(ast.newName(getSimpleNames("GridData.HORIZONTAL_ALIGN_CENTER")));
- mi.arguments().add(cc);
- constructorBlock.statements().add(ast.newExpressionStatement(mi));
// Button button = new Button(this,SWT.PUSH);
java 代码
- vdf = ast.newVariableDeclarationFragment();
- vdf.setName(ast.newSimpleName("button"));
- vds = ast.newVariableDeclarationStatement(vdf);
- vds.setType(ast.newSimpleType(ast.newSimpleName("Button")));
- constructorBlock.statements().add(vds);
- cc = ast.newClassInstanceCreation();
- cc.setName(ast.newSimpleName("Button"));
- vdf.setInitializer(cc);
- cc.arguments().add(ast.newThisExpression());
- cc.arguments().add(ast.newName(getSimpleNames("SWT.PUSH")));
// button.addSelectionListener(new SelectionAdapter() {});
java 代码
- mi = ast.newMethodInvocation();
- constructorBlock.statements().add(ast.newExpressionStatement(mi));
- mi.setExpression(ast.newSimpleName("button"));
- mi.setName(ast.newSimpleName("addSelectionListener"));
- ClassInstanceCreation ci = ast.newClassInstanceCreation();
- ci.setName(ast.newSimpleName("SelectionAdapter"));
- mi.arguments().add(ci);
- AnonymousClassDeclaration cd = ast.newAnonymousClassDeclaration();
- ci.setAnonymousClassDeclaration(cd);
?/span>一般情况下,我们都用相对\径来获取资源,q样的灵zL比较大.
比如当前cMؓcom/bbebfe/Test.class
而图像资源比?/span>sample.gif应该攄?/span>com/bbebfe/sample.gif
而如果这些图像资源放|在icons目录?/span>,则应该是com/bbebfe/icons/sample.gif
通过当前cL件的路径获取资源主要有如下几U方?/span>:
· 假设当前cMؓcom.bbebfe.Test
· 包所在的文g夹ؓbin
String imageName = "icons/sample.gif"
1, 通过Class.getResource()定位c\径下的资?/span>(bin/com/bbebfe/icons/sample.gif)
Class clazz = this.getClass();
URL url = clazz.getResource(imageName);
2,通过ClassLoader.getResource()定位包的根目录下的资?/span>(bin/icons/sample.gif)
Class clazz = this.getClass();
URLClassLoader loader = (URLClassLoader)clazz.getClassLoader();
URL url = loader.getResource(imageName);
3, 通过ClassLoader.findResource()提供自己定制的方式定位资?/span>
URL url = loader.findResource(imageName);
?/span>那么q三U方法有那些区别, 我们应该在何时用哪U方法呢?
· Class.getResource() Ҏ
该方法实际通过?/span>Class?/span>Class Loader?/span>getResource()Ҏ来获得资?/span>, 在调?/span>ClassLoader?/span>getResource()Ҏ之前, Class.getResource()Ҏ会对资源名称做一定的处理,构徏一个该资源的绝对名U?/span>(absolute name, 大意?/span>:
Q?/span>如果资源名称?/span>'/'('"u002f') 开?/span>, 则资源的l对名称?/span>'/'以后的部?/span>.
如果imageName?/span>"/icons/sample.gif", 则在q里会变?/span>"icons/sample.gif"
Q?/span>否则对于其他情况, l对名称是如下形式(l资源名U的前面加上modified_package_name/):
modified_package_name/resource_name (修正的包名称/资源名称)
其中修正的包名称含义是将当前对象所在的包名U?/strong>中的'.'('"u002e')替换?/span>'/'
如果ClassLoader.getResource()Ҏq回一个gؓnull?/span>URL, ?/span>Class.getResource()Ҏ最l会资源请求交l?/span>ClassLoader.getSystemResource(java.lang.String).
· ClassLoader.getResource() Ҏ
该对资源q行查找, 资源的名U是?/span>'/'分隔的\?/span>, q个Ҏ首先查找自己的父?/span>ClassLoader, pq?/span>ClassLoader来查找资?/span>(实际?/span>, 如果父亲的父亲不是空, 则父亲仍会向上提交查找请?/span>). 如果自己的父ClassLoader?/span>null, 则查?/span>Java虚拟Z内徏?/span>class loader, q将资源h提交l它?/span>, 如果q些操作都失败了, ?/span>ClassLoader会调用自qfindResource()Ҏ来查找资?/span>.
· ClassLoader.findResource() Ҏ
该方法在内部查找指定的资?/span>, 如果你实C自己?/span>Class Loader,则应该重载这个方法以自己特定的方式来查找cL件和资源.
?/span>通过以上的ȝ, 我们可以看到三点.
1, 无论?/span>getResource(), q是findResource(), q些Ҏ都只是资源的定位Ҏ, 最l都只是q回一?/span>URL, 只是对资源的定位而已, 我们随后应通过自己的方法来dq些资源. 而在Class?/span>ClassLoader中还定义的有getResourceAsStreamҎ, 该方法是getResource的增强版, q里׃介绍?/span>.
2,如果需要以cMؓ相对路径查找资源, 则应该调?/span>Class.getResource()Ҏ, 不要直接调用ClassLoader.getResource()Ҏ. 另外, 除非是你自己定义?/span>ClassLoaderq载了findResourceҎ,否则也不要直接调?/span>ClassLoader.findResourceҎ, 因ؓ?/span>Class.getResource()Ҏ?strong>会对资源名称作一定的处理, q在上面介绍?/span>, 下面举个实例:
假设我的当前cdEclipse工程Database?/span>, cL在的包是com.bbebfe.test, ?/span>icons目录攑֜bin/com/bbebfe/test/目录?/span>, 我需要得?/span>icons/sample.gif文g?/span>URL, 则调?/span>this.getClass().getResource()得到?/span>URL?/span>:
file:/E:/MyLife/MyProjects/Eclipse3.2/Database/bin/com/bbebfe/test/icons/disremove.gif
3, 有时候我们希望某?/span>jar库的囑փ资源在同一?/span>icons下统一理, 而不是ؓ每个包下面的ClassZ?/span>icons, 也就是说需要以库ؓ相对路径来查找资?/strong>, 此时则应该调?/span>ClassLoader.getResource()Ҏ, 举个例子:
·某个工程有如下的包结?/span>:
com.bbebfe.ui
com.bbebfe.test
com.bbebfe.database
·如果以类为相对\?/span>, 则在每个包下都必d立一?/span>icons目录, q放|相应的资源文g. 如下:
com.bbebfe.ui/icons/...
com.bbebfe.test/icons/...
com.bbebfe.database/icons/...
·而我们可能希望在根目录下攄一?/span>icons目录, 把所有资源放|在q里理, q样q可以防止资源的重复. 是如下形式
com.bbebfe.ui
com.bbebfe.test
com.bbebfe.database
icons/sample.gif ...
则此?strong>我们应该调用ClassLoader.getResourceҎ, ׃它没有对资源名称作处?/span>, 也就是说没有修正的包名d到资源名U前, 所以它会在cL在的包的根下L找资?/span>.(q行javaE序的语法是java com.bbebfe.ui.Test, 所?strong>根目?/strong>?/span>com目录的上U目?/span>).
?/span>最?/span>, ?/span>Java中对资源q行定位的方法有很多U?/span>, ?/span>Eclipse源代码中q有如下一D定位文件资源的代码, q没有时间研I?/span>, 以后再谈:
ProtectionDomain domain = Main.class.getProtectionDomain();
CodeSource source = null;
URL result = null;
if (domain != null)
source = domain.getCodeSource();//获得code source
if (source != null)
result = source.getLocation();//获得URL
String path = decode(result.getFile());//
// normalize to not have leading / so we can check the form
File file = new File(path);
path = file.toString().replace('""', '/');
// create a file URL (via File) to normalize the form (e.g., put
// the leading / on if necessary)
path = new File(path).toURL().getFile();
在JAVA环境中,一个Q务一般是׃个独立线E来引导实现的,独立U程可能调用一pd子线E。如果在执行q程中,某一个线E发生异常(产生的原因很多,比如软g升、运行环境改变、系l资抢占{)Q那么该U程׃停止q行Q直CơQ务重新被提交。对于实时环境来说当前Q务是p|的。我们无法预和完全避免异常的发生,但是可以通过一些技术手D|跟踪d的状态,从而及时发现问题ƈ恢复正常Q减损失?/p>
对于一个实时Q务而言Q执行效率是非常关键的,q意味着不可能考虑用非常复杂的方式来实CQ务监控,即ɘq样可以做的比较完善Q同时监控代码本w也会引入一些异常,q就要求监控E序必须单可靠,能够发现大多数问题,q能及时处理?
一个可能的单实现?
我们Ҏ个Q务加上一个监控的"?Q调度程序调用这??来完成对具体d的引导和监控Q相当于每个dh自治能力。这样做的好处有Q?
每个U程理论上有四种状态:
new | U程对象已经创徏Q但未启动Q不可运? |
runnable | 一旦有旉分片机制有空闲的CPU周期Q线E立卛_始运? |
dead | 从run()Ҏ退出后Q一个线E即消亡 |
blocked | U程可运行,但有某种东西ȝ了它。调度机制不l它分配MCPU旉Q直到它q入runnable状? |
在实际操作中Qؓ了便于描qͼ我们重新规定了线E的状态:
Actived | U程已被Ȁz,处于q行状? |
Sleeping | U程完成一个特定Q务后退出,q入休眠状? |
Dead | U程q行q程中发生异常,l止q行Q处于死亡状? |
Ҏ上述理论Q我们只需要对Actived状态的U程q行监控Q也只有对Actived状态监控才有意义,q是对监控模块做出逻辑化。那么如何实现监控模块对具体d的监控呢Q?
对具体Q务的监控方式有多U,Ҏd的不同,需要采用不同的监控代码Q但是在l构上基本相同。这和类的重载概忉|点相伹{本文附有一个简单的例子?
Ad每秒执行一个简单的代数q算 j = 1/ iQƈ打印l果。我们故意在其中讄了一个异帔R阱,使得执行q程中出Cơ被0除的术异常Q下面结合这个例子讲q监控原理?
Z监控AQ我们设计了一个监控线EM。M中定义了一些关键逻辑变量Q?
Keepchecking | 持箋监控标志 |
laststatus | 保存上次监控状? |
maydeadtimes | 监控U程可能M的计数器 |
maydeadtimeout | 定义判断U程M的边界条? |
deadtimes | 监控U程Mơ数的计数器 |
deadtimeout | 定义判断U程不正常的边界条g |
Z适应监控Q在Ad中相应增加一些可以被监控的状态和行ؓQ?
dead | ȝ态标? |
dead = !dead; | 改变状? |
如果是因为系l偶然因素导致AMQ那么在随后的新的Q务启动过E中一般可以顺利完成。但是万一׃环境参数改变或Y件升U存在版本缺PA可能始终会生异常,那么M是否需要耐心地监控下dQ一个Ş象的例子是:如果你连l?ơ开机都p|Q你是否会怀疑机器有问题Q当Ӟ你会Q那么M也应该会?
Z对Ad重复多次M有一个统计,M中又引入了另外对计数器和边界|deadtimes和deadtimeoutQ,和你开计算机的q程一P如果q箋nơ都发现A有问题,可以基本肯定不是׃偶然因素引v的,需要对A的代码或pȝ的环境进行检查。M会发出告警,通知必须要对Aq行审查了,然后清空AQ自p?a class="channel_keylink" target="_blank">安全退出。如果在核心调度E序中设|一个标志接受M们的告警Q就可以有够理q止其他Q务的执行。可以看见,在Ad发生异常期间QM承担了核心调度程序的l护功能。特别是当Q务数量比较多的情况,核心调度E序只能采用排队方式处理d异常Q而且׃处理异常的复杂程度不同,无法保证对多d异常的实时处理?
q要考虑正常情况下A和M的关pR核心调度程序通过M启动Ad后,M处于持箋监控状态,当A正常l束d后,A需要通知Ml束监控Q这P当Aq入休眠状态后QM也不会占用内存空_提高了系l资源的利用率?
通过以上描述Q可以看刎ͼ上述监控思想h清晰的概念和可操作性,占用资源,Z证系l连l稳定运行创造了条g?
具体代码实现附后?
q行l果如下Q?
|
通过l制定Q务线E增加监控线E,可以很好地解军_时多d环境下的安全监控问题Q同旉免了核心调度U程事务q分复杂的问题。实践证明,该方法复杂度,占用资源,q行可靠Q适合复杂条g下的多Q务环境?
5. 源代码:
// 核心调度E序 public class mythread { public mythread() { } public static void main(String[] args) { M m = new M(); } } // A dU程 class A extends Thread { public static boolean dead = false; M m; A(M m){ m = m; start(); } public void run(){ try{ for(int i=-3;i<= 5;i++){ int j=1/i; // Zؓ讄q程中陷? dead = !dead; // zd状? System.out.println("i=" + i + ": status=" + dead); try{ sleep(2000); } catch(InterruptedException ie){ System.out.println("A is Interrupted!"); } } m.Keepchecking = false; //A 正常l束后关闭监控线E? System.out.println("A is Ending M"); } catch(Exception e){ System.out.println("A become Exception!"); } } } // 监控U程 class M extends Thread{ public static boolean Keepchecking = true; // 持箋监控标志 boolean laststatus; //保存上次监控状? int maydeadtimes = 0; //监控U程可能M的计数器 int maydeadtimeout = 3;//定义判断U程M的边界条? int deadtimes = 0; //监控U程Mơ数的计数器 int deadtimeout = 3; //定义判断U程不正常的边界条g A a; M(){start();} public void run(){ schedule(); while(Keepchecking){ laststatus = a.dead; try{ sleep(2000); } catch(InterruptedException e){ System.out.println("M is Interrupted!"); } System.out.println("M read A status = " + a.dead); if(laststatus == a.dead ){ if(++maydeadtimes >= maydeadtimeout){ if(++deadtimes >= deadtimeout){ System.out.println("Alert! A is unstable, M will stop it"); a = null; break; } else{ System.out.println( "A is deaded!"); schedule(); System.out.println("M is restarting A!\n____________________________\n"); } } } else{ maydeadtimes = 0; } } } private void schedule(){ A a = new A(this); } }
http://lavasoft.blog.51cto.com/
一、Java中的日期概述
日期在Java中是一块非常复杂的内容Q对于一个日期在不同的语a国别环境中,日期的国际化Q日期和旉之间的{换,日期的加减运,日期的展C格式都是非常复杂的问题?
在Java中,操作日期主要涉及C下几个类Q?
1、java.util.Date
c?Date 表示特定的瞬__到毫U。从 JDK 1.1 开始,应该使用 Calendar cd现日期和旉字段之间转换Q?DateFormat cL格式化和分析日期字符丌ӀDate 中的把日期解释ؓq、月、日、小时、分钟和U值的Ҏ已废弃?
2、java.text.DateFormatQ抽象类Q?
DateFormat 是日?旉格式化子cȝ抽象c,它以与语a无关的方式格式化q分析日期或旉。日?旉格式化子c(?SimpleDateFormatQ允许进行格式化Q也是日期 -> 文本Q、分析(文本-> 日期Q和标准化。将日期表示?Date 对象Q或者表CZؓ?GMTQ格林尼L准时_1970 q_1 ?1 ?00:00:00 q一d始的毫秒数?
3、java.text.SimpleDateFormatQDateFormat的直接子c)
SimpleDateFormat 是一个以与语a环境相关的方式来格式化和分析日期的具体类。它允许q行格式化(日期 -> 文本Q、分析(文本 -> 日期Q和规范化?
SimpleDateFormat 使得可以选择M用户定义的日?旉格式的模式。但是,仍然通过 DateFormat 中的 getTimeInstance、getDateInstance ?getDateTimeInstance 来新的创建日?旉格式化程序?
4、java.util.CalendarQ抽象类Q?
Calendar cL一个抽象类Q它为特定瞬间与一l诸?YEAR、MONTH、DAY_OF_MONTH、HOUR {?日历字段之间的{换提供了一些方法,qؓ操作日历字段Q例如获得下星期的日期)提供了一些方法。瞬间可用毫U值来表示Q它是距历元Q即格林威治标准旉 1970 q?1 ?1 日的 00:00:00.000Q格里高利历Q的偏移量?
与其他语a环境敏感cMPCalendar 提供了一个类Ҏ getInstanceQ以获得此类型的一个通用的对象。Calendar ?getInstance Ҏq回一?Calendar 对象Q其日历字段已由当前日期和时间初始化?
5、java.util.GregorianCalendarQCalendar的直接子c)
GregorianCalendar ?Calendar 的一个具体子c,提供了世界上大多数国家用的标准日历pȝ?
GregorianCalendar 是一U合日历,在单一间断性的支持下同时支持儒略历和格里高利历pȝQ在默认情况下,它对应格里高利日历创立时的格里高利历日期Q某些国家是?1582 q?10 ?15 日创立,在其他国家要晚一些)。可p用方通过调用 setGregorianChange() 来更改v始日期?
二、java.util.Date的?
1、java.util.Date的API?
c?java.util.Date 表示特定的瞬__到毫U。提供了很多的方法,但是很多已经q时Q不推荐使用Q下面仅仅列出没有过时的ҎQ?
构造方法摘?
-------------
Date()
分配 Date 对象q用当前旉初始化此对象Q以表示分配它的旉Q精到毫秒Q?
Date(long date)
分配 Date 对象q初始化此对象,以表C从标准基准时_UCؓ“历元QepochQ?#8221;Q即 1970 q?1 ?1 ?00:00:00 GMTQ以来的指定毫秒数?
Ҏ摘要
-------------
boolean after(Date when)
试此日期是否在指定日期之后?
boolean before(Date when)
试此日期是否在指定日期之前?
Object clone()
q回此对象的副本?
int compareTo(Date anotherDate)
比较两个日期的顺序?
boolean equals(Object obj)
比较两个日期的相{性?
long getTime()
q回?1970 q?1 ?1 ?00:00:00 GMT 以来?Date 对象表示的毫U数?
int hashCode()
q回此对象的哈希码倹{?
void setTime(long time)
讄?Date 对象Q以表示 1970 q?1 ?1 ?00:00:00 GMT 以后 time 毫秒的时间点?
String toString()
把此 Date 对象转换Z下Ş式的 StringQ?dow mon dd hh:mm:ss zzz yyyy 其中Q?
dow 是一周中的某一?(Sun, Mon, Tue, Wed, Thu, Fri, Sat)?
mon 是月?(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)?
dd 是一月中的某一天(01 ?31Q,昄Z位十q制数?
hh 是一天中的小Ӟ00 ?23Q,昄Z位十q制数?
mm 是小时中的分钟(00 ?59Q,昄Z位十q制数?
ss 是分钟中的秒敎ͼ00 ?61Q,昄Z位十q制数?
zzz 是时区(q可以反映夏令时Q。标准时区羃写包括方?parse 识别的时区羃写。如果不提供时区信息Q则 zzz 为空Q即Ҏ不包括Q何字W?
yyyy 是年份,昄?4 位十q制数?/p>
下面是一个Datecȝl合实例:
import java.util.Date;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 8:45:44
* 日期试
*/
public class TestDate {
public static void main(String args[]) {
TestDate nowDate = new TestDate();
nowDate.getSystemCurrentTime();
nowDate.getCurrentDate();
}
/**
* 获取pȝ当前旉
* System.currentTimeMillis()q回pȝ当前旉Q结果ؓ1970q?????U开始,到程序执行取得系l时间ؓ止所l过的毫U数
* 1U=1000毫秒
*/
public void getSystemCurrentTime() {
System.out.println("----获取pȝ当前旉----");
System.out.println("pȝ当前旉 = " + System.currentTimeMillis());
}
/**
* 通过Datec获取当前日期和当前旉
* date.toString()把日期{换ؓdow mon dd hh:mm:ss zzz yyyy
*/
public void getCurrentDate() {
System.out.println("----获取pȝ当前日期----");
//创徏q初始化一个日期(初始gؓ当前日期Q?
Date date = new Date();
System.out.println("现在的日期是 = " + date.toString());
System.out.println("?970q?????U开始至今所l历的毫U数 = " + date.getTime());
}
}
q行l果:
----获取pȝ当前旉----
pȝ当前旉 = 1196413077278
----获取pȝ当前日期----
现在的日期是 = Fri Nov 30 16:57:57 CST 2007
?970q?????U开始至今所l历的毫U数 = 1196413077278
Process finished with exit code 0
2、java.text.DateFormat抽象cȝ使用
DateFormat 是日?旉格式化子cȝ抽象c,它以与语a无关的方式格式化q分析日期或旉。日?旉格式化子c(?SimpleDateFormatQ允许进行格式化Q也是日期 -> 文本Q、分析(文本-> 日期Q和标准化。将日期表示?Date 对象Q或者表CZؓ?GMTQ格林尼L准时_1970 q_1 ?1 ?00:00:00 q一d始的毫秒数?
DateFormat 提供了很多类ҎQ以获得Z默认或给定语a环境和多U格式化风格的默认日?旉 Formatter。格式化风格包括 FULL、LONG、MEDIUM ?SHORT。方法描qC提供了用这些风格的更多l节和示例?
DateFormat 可帮助进行格式化q分析Q何语a环境的日期。对于月、星期,甚至日历格式Q阴历和阛_Q,其代码可完全与语a环境的约定无兟?
要格式化一个当前语a环境下的日期Q可使用某个静态工厂方法:
myString = DateFormat.getDateInstance().format(myDate);
如果格式化多个日期,那么获得该格式ƈ多次使用它是更ؓ高效的做法,q样pȝ׃必多ơ获取有关环境语a和国家约定的信息了?
DateFormat df = DateFormat.getDateInstance();
for (int i = 0; i < myDate.length; ++i) {
output.println(df.format(myDate[i]) + "; ");
}
要格式化不同语言环境的日期,可在 getDateInstance() 的调用中指定它?
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
q可使用 DateFormat q行分析?
myDate = df.parse(myString);
使用 getDateInstance 来获得该国家的标准日期格式。另外还提供了一些其他静态工厂方法。?getTimeInstance 可获得该国家的时间格式。?getDateTimeInstance 可获得日期和旉格式。可以将不同选项传入q些工厂ҎQ以控制l果的长度(?SHORT ?MEDIUM ?LONG 再到 FULLQ。确切的l果取决于语a环境Q但是通常Q?
SHORT 完全为数字,?12.13.52 ?3:30pm
MEDIUM 较长Q如 Jan 12, 1952
LONG 更长Q如 January 12, 1952 ?3:30:32pm
FULL 是完全指定,?Tuesday, April 12, 1952 AD ?3:30:42pm PST?
如果愿意Q还可以在格式上讄时区。如果想Ҏ式化或分析施加更多的控制Q或者给予用h多的控制Q,可以试从工厂Ҏ所获得?DateFormat 强制转换?SimpleDateFormat。这适用于大多数国家Q只是要C其攑օ一?try 代码块中Q以防遇到特D的格式?
q可以用借助 ParsePosition ?FieldPosition 的分析和格式化方法Ş式来Q逐步地分析字W串的各部分?寚wL特定的字D,或者找出字W串在屏q上的选择位置?
DateFormat 不是同步的。徏议ؓ每个U程创徏独立的格式实例。如果多个线E同时访问一个格式,则它必须保持外部同步?
3、java.text.SimpleDateFormatQDateFormat的直接子c)的?
SimpleDateFormat 是一个以与语a环境相关的方式来格式化和分析日期的具体类。它允许q行格式化(日期 -> 文本Q、分析(文本 -> 日期Q和规范化?
SimpleDateFormat 使得可以选择M用户定义的日?旉格式的模式。但是,仍然通过 DateFormat 中的 getTimeInstance、getDateInstance ?getDateTimeInstance 来新的创建日?旉格式化程序。每一个这LcL法都能够q回一个以默认格式模式初始化的日期/旉格式化程序。可以根据需要?applyPattern Ҏ来修Ҏ式模式。有关用这些方法的更多信息Q请参阅 DateFormat?
日期和时间模?
日期和时间格式由日期和时间模?字符串指定。在日期和时间模式字W串中,未加引号的字?'A' ?'Z' ?'a' ?'z' 被解释ؓ模式字母Q用来表C日期或旉字符串元素。文本可以用单引号 (') 引v来,以免q行解释?''" 表示单引受所有其他字W均不解释;只是在格式化时将它们单复制到输出字符Ԍ或者在分析时与输入字符串进行匹配?
定义了以下模式字母(所有其他字W?'A' ?'Z' ?'a' ?'z' 都被保留Q:
字母 日期或时间元?表示 CZ
G Era 标志W?Text AD
y q?Year 1996; 96
M q中的月?Month July; Jul; 07
w q中的周?Number 27
W 月䆾中的周数 Number 2
D q中的天?Number 189
d 月䆾中的天数 Number 10
F 月䆾中的星期 Number 2
E 星期中的天数 Text Tuesday; Tue
a Am/pm 标记 Text PM
H 一天中的小时数Q?-23Q?Number 0
k 一天中的小时数Q?-24Q?Number 24
K am/pm 中的时敎ͼ0-11Q?Number 0
h am/pm 中的时敎ͼ1-12Q?Number 12
m 时中的分钟?Number 30
s 分钟中的U数 Number 55
S 毫秒?Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -0800
更多的参考信息可以查看JDK API文档,下面l出一个综合实?
import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 11:20:58
* To change this template use File | Settings | File Templates.
*/
public class TestSimpleDateFormat {
public static void main(String args[]) throws ParseException {
TestSimpleDateFormat test = new TestSimpleDateFormat();
test.testDateFormat();
}
public void testDateFormat() throws ParseException {
//创徏日期
Date date = new Date();
//创徏不同的日期格?
DateFormat df1 = DateFormat.getInstance();
DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss EE");
DateFormat df3 = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA); //产生一个指定国家指定长度的日期格式Q长度不同,昄的日期完整性也不同
DateFormat df4 = new SimpleDateFormat("yyyyqMM月dd?hh时mm分ssU?EE", Locale.CHINA);
DateFormat df5 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss EEEEEE", Locale.US);
DateFormat df6 = new SimpleDateFormat("yyyy-MM-dd");
DateFormat df7 = new SimpleDateFormat("yyyyqMM月dd?);
//日期按照不同格式进行输?
System.out.println("-------日期按照不同格式进行输?-----");
System.out.println("按照Java默认的日期格式,默认的区?: " + df1.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE Q系l默认区?:" + df2.format(date));
System.out.println("按照日期的FULL模式Q区域设|ؓ中文 : " + df3.format(date));
System.out.println("按照指定格式 yyyyqMM月dd?hh时mm分ssU?EE Q区域ؓ中文 : " + df4.format(date));
System.out.println("按照指定格式 yyyy-MM-dd hh:mm:ss EE Q区域ؓ国 : " + df5.format(date));
System.out.println("按照指定格式 yyyy-MM-dd Q系l默认区?: " + df6.format(date));
//符合该格式的字W串转换为日期,若格式不盔RQ则会出?
Date date1 = df1.parse("07-11-30 下午2:32");
Date date2 = df2.parse("2007-11-30 02:51:07 星期?);
Date date3 = df3.parse("2007q?1?0?星期?);
Date date4 = df4.parse("2007q?1?0?02?1?8U?星期?);
Date date5 = df5.parse("2007-11-30 02:51:18 Friday");
Date date6 = df6.parse("2007-11-30");
System.out.println("-------输出字W串转换为日期的l果------");
System.out.println(date1);
System.out.println(date2);
System.out.println(date3);
System.out.println(date4);
System.out.println(date5);
System.out.println(date6);
}
}
q行l果:
-------日期按照不同格式进行输?-----
按照Java默认的日期格式,默认的区?: 07-11-30 下午5:04
按照指定格式 yyyy-MM-dd hh:mm:ss EE Q系l默认区?:2007-11-30 05:04:10 星期?
按照日期的FULL模式Q区域设|ؓ中文 : 2007q?1?0?星期?
按照指定格式 yyyyqMM月dd?hh时mm分ssU?EE Q区域ؓ中文 : 2007q?1?0?05?4?0U?星期?
按照指定格式 yyyy-MM-dd hh:mm:ss EE Q区域ؓ国 : 2007-11-30 05:04:10 Friday
按照指定格式 yyyy-MM-dd Q系l默认区?: 2007-11-30
-------输出字W串转换为日期的l果------
Fri Nov 30 14:32:00 CST 2007
Fri Nov 30 02:51:07 CST 2007
Fri Nov 30 00:00:00 CST 2007
Fri Nov 30 02:51:18 CST 2007
Fri Nov 30 02:51:18 CST 2007
Fri Nov 30 00:00:00 CST 2007
Process finished with exit code 0
4、java.util.CalendarQ抽象类Q?
java.util.Calendar是个抽象c,是系l时间的抽象表示Q它为特定瞬间与一l诸?YEAR、MONTH、DAY_OF_MONTH、HOUR {?日历字段之间的{换提供了一些方法,qؓ操作日历字段Q例如获得下星期的日期)提供了一些方法。瞬间可用毫U值来表示Q它是距历元Q即格林威治标准旉 1970 q?1 ?1 日的 00:00:00.000Q格里高利历Q的偏移量?
与其他语a环境敏感cMPCalendar 提供了一个类Ҏ getInstanceQ以获得此类型的一个通用的对象。Calendar ?getInstance Ҏq回一?Calendar 对象Q其日历字段已由当前日期和时间初始化?
一个Calendar的实例是pȝ旉的抽象表C,从Calendar的实例可以知道年月日星期月䆾时区{信息。CalendarcM有一个静态方法get(int x),通过q个Ҏ可以获取到相兛_例的一些|q月日星期月份等Q信息。参数x是一个量|在Calendar中有定义?
Calendar中些陷阱Q很Ҏ掉下去:
1、Calendar的星期是从周日开始的Q常量gؓ0?
2、Calendar的月份是从一月开始的Q常量gؓ0?
3、Calendar的每个月的第一天gؓ1?
5、java.util.GregorianCalendarQCalendar的直接子c)
GregorianCalendar ?Calendar 的一个具体子c,提供了世界上大多数国家用的标准日历pȝ。结合Calendar抽象cM用?
下面l出一个综合实例看看Calendarcȝ用法Q?
import java.util.*;
import java.text.SimpleDateFormat;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-30
* Time: 15:06:57
* Calendar的用测?
*/
public class TestCalendar {
public static void main(String args[]) {
TestCalendar testCalendar = new TestCalendar();
testCalendar.testCalendar();
}
public void testCalendar() {
//创徏Calendar的方?
Calendar now1 = Calendar.getInstance();
Calendar now2 = new GregorianCalendar();
Calendar now3 = new GregorianCalendar(2007, 10, 30);
Calendar now4 = new GregorianCalendar(2007, 10, 30, 15, 55); //陷阱:Calendar的月份是0~11
Calendar now5 = new GregorianCalendar(2007, 10, 30, 15, 55, 44);
Calendar now6 = new GregorianCalendar(Locale.US);
Calendar now7 = new GregorianCalendar(TimeZone.getTimeZone("GMT-8:00"));
//通过日期和毫U数讄Calendar
now2.setTime(new Date());
System.out.println(now2);
now2.setTimeInMillis(new Date().getTime());
System.out.println(now2);
//定义日期的中文输出格?q输出日?
SimpleDateFormat df = new SimpleDateFormat("yyyyqMM月dd?hh时mm分ssU?E", Locale.CHINA);
System.out.println("获取日期中文格式化化输出Q? + df.format(now5.getTime()));
System.out.println();
System.out.println("--------通过Calendar获取日期中年月日{相关信?-------");
System.out.println("获取q_" + now5.get(Calendar.YEAR));
System.out.println("获取?月䆾是从0开始的)Q? + now5.get(Calendar.MONTH));
System.out.println("获取日:" + now5.get(Calendar.DAY_OF_MONTH));
System.out.println("获取Ӟ" + now5.get(Calendar.HOUR));
System.out.println("获取分:" + now5.get(Calendar.MINUTE));
System.out.println("获取U:" + now5.get(Calendar.SECOND));
System.out.println("获取上午、下午:" + now5.get(Calendar.AM_PM));
System.out.println("获取星期数?星期是从周日开始的)Q? + now5.get(Calendar.DAY_OF_WEEK));
System.out.println();
System.out.println("---------通用星期中文化{?--------");
String dayOfWeek[] = {"", "?, "一", "?, "?, "?, "?, "?};
System.out.println("now5对象的星期是:" + dayOfWeek[now5.get(Calendar.DAY_OF_WEEK)]);
System.out.println();
System.out.println("---------通用月䆾中文化{?--------");
String months[] = {"一?, "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一?, "十二?};
System.out.println("now5对象的月份是: " + months[now5.get(Calendar.MONTH)]);
}
}
q行l果Q?
java.util.GregorianCalendar[time=1196414388324,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2007,MONTH=10,WEEK_OF_YEAR=48,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=334,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=19,SECOND=48,MILLISECOND=324,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1196414388324,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2007,MONTH=10,WEEK_OF_YEAR=48,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=334,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=19,SECOND=48,MILLISECOND=324,ZONE_OFFSET=28800000,DST_OFFSET=0]
获取日期中文格式化化输出Q?007q?1?0?03?5?4U?星期?
--------通过Calendar获取日期中年月日{相关信?-------
获取q_2007
获取?月䆾是从0开始的)Q?0
获取日:30
获取Ӟ3
获取分:55
获取U:44
获取上午、下午:1
获取星期数?星期是从周日开始的)Q?
---------通用星期中文化{?--------
now5对象的星期是:?
---------通用月䆾中文化{?--------
now5对象的月份是: 十一?
Process finished with exit code 0
三、ȝ
Java中日期的l常有一下五个方面:
1、创建日?
2、日期格式化昄
3、日期的转换Q主要是和字W串之间的相互{换)
4、日期中q、月、日、时、分、秒、星期、月份等获取?
5、日期的大小比较、日期的加减?
q也是学习java日期操作的难点和关键Q掌握了q些Q日期问题一般难不倒你?
关于日期的大比较和加减在API文档中都有详的描述?/p>
做项目的时候,用到了JfreeChart。但是在旉轴刻度的昄上出C问题。在讄dateAxis.setAutoTickUnitSelection(true)后,当时间间隔比较小的时候,同一旉D会昄多个相同的时间。我一直没有查出原因,在网上也没有搜到相关的问题和解决办法Q感觉是JfreeChart的问题。一直想了解JfreeChart是如何自动设|时间刻度,但没有头l。于是,增加了判断当旉间隔 >10天的时候,自动讄旉dQ反之,?天ؓ间隔讄。这样问题解决了Q经q测试,也没有发现相同时间刻度的情况的出现?
long maximumDate = dateAxis.getMaximumDate().getTime();
long minimumDate = dateAxis.getMinimumDate().getTime();
long times = (maximumDate - minimumDate)/(3600*24*1000);
if(times<10){
dateAxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, 1, dateFormat));
}
else{
dateAxis.setAutoTickUnitSelection(true);
}
管q样q是感觉q样解决问题不是很好?/p>
在解决问题过E中Q遇C关于Ҏ期的处理问题。在|上找了资料Q发C面那不错还Q就拿过来了Q以后遇到日期问题也好有个参考,不用再东找西找了?/p>