(持续更新中。。。)
1. Calendar -- set() add() roll()
(1)对于某些特别时间的解释可能会有某些歧义,可以用下列方式解决:
23:59 是一天中的最后一分钟,而 00:00 是下一天的第一分钟。因此,1999 年 12 月 31 日的 23:59 < 2000 年 1 月 1 日的 00:00。
尽管从历史上看不够精确,但午夜也属于 "am",,中午属于 "pm",所以在同一天,12:00 am ( 午夜 ) < 12:01 am,12:00 pm ( 中午 ) < 12:01 pm。
----------------------- set() -----------------------
set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。
----------------------- add() -----------------------
add() 有两条规则:
Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 31, 0, 0 , 0); //2000-8-31
cal1.add(Calendar.MONTH, 1); //2000-9-31 => 2000-10-1, 对吗?
System.out.println(cal1.getTime()); //结果是 2000-9-30
----------------------- roll() -----------------------
Roll() 的规则只有一条:
当被修改的字段超出它可以的范围时,那么比它大的字段不会被修正。
2.DecimalFormat -> NumberFormat -> Format
在Java中,DecimalFormat类为格式化输入输出提供了比C/C++更加强大的面向对象和国际化形式。DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字。该类设计有各种功能,使其能够解析和格式化任意语言环境中的数,包括对西方语言、阿拉伯语和印度语数字的支持。它还支持不同类型的数,包括整数 (123)、定点数 (123.4)、科学记数法表示的数 (1.23E4)、百分数 (12%) 和金额 ($123)。所有这些内容都可以本地化。
DecimalFormat 包含一个 模式 和一组 符号。
模式
DecimalFormat 模式具有下列语法:
模式:
正数模式
正数模式;负数模式
正数模式:
前缀opt 数字后缀opt
负数模式:
前缀opt 数字后缀opt
前缀:
除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符
后缀:
除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符
数字:
整数 指数opt
整数.小数 指数opt
整数:
最小整数
#
# 整数
# , 整数
最小整数:
0
0 最小整数
0 , 最小整数
小数:
最小小数opt 可选小数opt
最小小数:
0 最小小数opt
可选小数:
# 可选小数opt
指数:
E 最小指数
最小指数:
0 最小指数opt
舍入:
DecimalFormat 提供 RoundingMode 中定义的舍入模式进行格式化。默认情况下,它使用 RoundingMode.HALF_EVEN。
同步:
DecimalFormat 通常不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问某个格式,则必须保持外部同步。
符号 |
位置 |
国际化? |
含义 |
0 |
数字 |
是 |
阿拉伯数字,如果不存在则显示为 0 |
# |
数字 |
是 |
阿拉伯数字,如果不存在则不显示 |
. |
数字 |
是 |
小数分隔符或货币小数分隔符 |
- |
数字 |
是 |
减号 |
, |
数字 |
是 |
分组分隔符 |
E |
数字 |
是 |
分隔科学计数法中的尾数和指数。在前缀或后缀中无需加引号。 |
; |
子模式边界 |
是 |
分隔正数和负数子模式 |
% |
前缀或后缀 |
是 |
乘以 100 并显示为百分数 |
\u2030 |
前缀或后缀 |
是 |
乘以 1000 并显示为千分数 |
¤ (\u00A4) |
前缀或后缀 |
否 |
货币记号,由货币符号替换。如果两个同时出现,则用国际货币符号替换。如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符。 |
' |
前缀或后缀 |
否 |
用于在前缀或或后缀中为特殊字符加引号,例如 "'#'#" 将 123 格式化为 "#123"。要创建单引号本身,请连续使用两个单引号:"# o''clock"。 |
以下是使用了其中部分模式的例子。
package com.java.text;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
public class NUMBERFORMAT {
public static void main(String[] args) {
/* double input = 1234.5678;
// NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.CHINA);
// NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.JAPAN);
// NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.UK);
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
String result = currencyFormat.format(input);
System.out.println(result);*/
/* double input = 0.567878;
NumberFormat percentFormat = NumberFormat.getPercentInstance(Locale.CHINA);
percentFormat.setMinimumFractionDigits(3);
percentFormat.setMaximumFractionDigits(4);
String result = percentFormat.format(input);
System.out.println(result);*/
String pattern = "#,###.0#";//比较常用的数字格式输出. 如果整数部分不够4位,则不显示。小数部分如果不够2位,则不显示。
DecimalFormat decimalFormat = new DecimalFormat(pattern);
double input = 123.127;
String result = decimalFormat.format(input);
System.out.println(result);
pattern = "0,000.0#";//比较常用的数字格式输出. 如果整数部分不够4位,则显示为0.小数部分如果不够2位,则不显示
decimalFormat.applyPattern(pattern);
input = -123.7;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "0.000E0#";//若要明确显示两位指数,则改成0.000E00
decimalFormat.applyPattern(pattern);
input = 123.78;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "#0.##%";//百分数
decimalFormat.applyPattern(pattern);
input = 0.2778;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "#0.##\u2030";//千分数
decimalFormat.applyPattern(pattern);
input = 0.2778;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "\u00A4###,###,000.##";//货币
decimalFormat.applyPattern(pattern);
input = 277845675;
result = decimalFormat.format(input);
System.out.println(result);
decimalFormat = new DecimalFormat(pattern, new DecimalFormatSymbols(Locale.US));//改变环境
input = 277845675;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "###.00 m/s";//前缀或者后缀
decimalFormat.applyPattern(pattern);
input = 75;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "'###'###.00'###'";//特殊的前缀或者后缀(1特殊字符 2单引号本身)
decimalFormat.applyPattern(pattern);
input = 75;
result = decimalFormat.format(input);
System.out.println(result);
pattern = "00 o''clock";//特殊的前缀或者后缀(1特殊字符 2单引号本身)
decimalFormat.applyPattern(pattern);
input = 15;
result = decimalFormat.format(input);
System.out.println(result);
}
}
结果:
123.13
-0,123.7
1.2378E2
27.78%
277.8‰
¥277,845,675
$277,845,675
75.00 m/s
###75.00###
15 o'clock
3.
4.
5.
6.
7.
8.
9.
10.