Java格式化时间(面试题)

发布 : 2019-03-18 分类 : Java 浏览 :

题目

现有一个日期数据结构如下(对于不同语言自行实现类似的结构):

1
2
3
4
5
6
7
8
public class Date  {
public int Year;
public int Month;
public int Day;
public int Hour;
public int Minute;
public int Second;
}

现要求编写一个DateFomatter将如上结构的Date数据格式化成特定结构的字符串,格式描述如下

符号 含义
yyyy 4位数字表示的年份,不足4位用0补齐,如2001,2012,0001
yy 2位数字表示的年份,不足2位用0补齐,如01,12,16
M 至少用1位表示的月份,如1,12
dd 2位数字表的日期,不足2位用0补齐,如08,30
d 至少用1位表示的日期,如8,30
HH 2位数字表示24小时制小时,不足2位用0补齐,如02,23
H 至少用1位表示的24小时制小时,如2,23
hh 2位数字表示12小时制小时,不足2位用0补齐,如02,12
h 至少用1位表示的12小时制小时,如2,12
mm 2位数字表示的分钟,不足2位用0补齐,如00,59
m 至少用1位数字表示的分钟,如0,59
ss 2位数字表示的秒数,不足2位用0补齐,如00,59
s 至少用1位数字表示的秒数,如0,59
其它字符 直接输出

注:其余任何使用y,M,d,H,h,m,s字符且不满足上述pattern的格式均视为无效格式,如hhh,y,yyyyy等,遇 到无效格式是formatter应输出invalid format

样例: 对于数据
{ Year: 2001, Month: 11, Day: 21, Hour: 13, Mintue: 58 Second: 8 }

格式 结果
yyyy­MM­ddTHH:mm:ss 2001­11­21T13:58:08
yy­M­d // H:m:s 01­11­21 // 13:58:8
d/m/yyyy 21/11/2001
hh:mm:ss 01:58:08
hxmxs 1x58x8
“yyyy” “2001”
yyyy­yy 2001­01
yyyy­MM­dd,yy­M­d 2001­11­21,01­11­21
HHH invalid format
yyy­MM invalid format

解题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

/**
* @author duiliu
* 2019/3/18
*/
public class DateDemo {
// 测试
public static void main(final String[] args) {
final Date date = new Date(2019, 2, 12, 11, 03, 56);
final DateFomatter dateFomatter1 = new DateFomatter("yyyy\\u00ADMM\\u00ADddTHH:mm:ss");
System.out.println("1\t" +
dateFomatter1.format(date)
);

final DateFomatter dateFomatter2 = new DateFomatter("yy\\u00ADM\\u00ADd // H:m:s");
System.out.println("2\t" +
dateFomatter2.format(date)
);

final DateFomatter dateFomatter3 = new DateFomatter("d/m/yyyy");
System.out.println("3\t" +
dateFomatter3.format(date)
);

final DateFomatter dateFomatter4 = new DateFomatter("hh:mm:ss");
System.out.println("4\t" +
dateFomatter4.format(date)
);

final DateFomatter dateFomatter5 = new DateFomatter(
"yyyy\u00ADMM\u00ADdd,yy\u00ADM\u00ADd");
System.out.println("5\t" +
dateFomatter5.format(date)
);

final DateFomatter dateFomatter6 = new DateFomatter(
"hxmxs");
System.out.println("6\t" +
dateFomatter6.format(date)
);
}
}

// 题目给出的时间数据结构
class Date {
public int Year;
public int Month;
public int Day;
public int Hour;
public int Minute;
public int Second;

public Date(final int year, final int month, final int day, final int hour, final int minute,
final int second) {
Year = year;
Month = month;
Day = day;
Hour = hour;
Minute = minute;
Second = second;
}
}

// 时间格式化类
class DateFomatter {
private final String formatStr;
static final Exception InvalidException = new Exception("invalid format");

public DateFomatter(final String format) {
this.formatStr = format;
}

public String format(final Date date) {
char ch = ' ';
int i = 0, j = 1;
final StringBuilder sb = new StringBuilder();
try {
while (i++ < formatStr.length()) {
j = 1;
while (i < formatStr.length() && (ch = formatStr.charAt(i)) == formatStr.charAt(
i - 1)) {
i++;
j++;
}
sb.append(formatDate(formatStr.charAt(i - 1), j, date));
}
} catch (final Exception e) {
return e.getMessage();
}
return sb.toString();
}

private String formatDate(final char ch, final int length, final Date date) throws Exception {
switch (ch) {
case 'y':
return formatTwoOrFour(length, date.Year);
case 'M':
return formatOneOrTwo(length, date.Month);
case 'd':
return formatOneOrTwo(length, date.Day);
case 'H':
return formatOneOrTwo(length == 1 && date.Hour > 10 ? 2 : length, date.Hour);
case 'h':
return formatOneOrTwo(length == 1 && date.Hour > 10 ? 2 : length, date.Hour % 12);
case 'm':
return formatOneOrTwo(length == 1 && date.Minute > 10 ? 2 : length, date.Minute);
case 's':
return formatOneOrTwo(length == 1 && date.Second > 10 ? 2 : length, date.Second);
default:
return ch + "";
}
}

private String intToString(final int needLength, final int number) {
int length = 0;
int temp = number;
final StringBuilder sb = new StringBuilder();
while (temp > 0 && length++ < needLength) {
sb.append(temp % 10);
temp /= 10;
}
while (length++ < needLength) {
sb.append(0);
}
return sb.reverse().toString();
}

private String formatOne(final int number) {
return intToString(1, number);
}

private String formatTwo(final int number) {
return intToString(2, number);
}

private String formatFour(final int number) {
return intToString(4, number);
}

private String formatOneOrTwo(final int length, final int number) throws Exception {
if (length == 1) {
return formatOne(number);
} else if (length == 2) {
return formatTwo(number);
}
throw InvalidException;
}

private String formatTwoOrFour(final int length, final int number) throws Exception {
if (length == 2) {
return formatTwo(number);
} else if (length == 4) {
return formatFour(number);
}
throw InvalidException;
}

}

结果:

1
2
3
4
5
6
1	2019\u0AD02\u0AD12T11:03:56
2 19\u0AD2\u0AD2 / 11:3:56
3 2/3/2019
4 11:03:56
5 2019­02­12,19­2­2
6 11x3x56
本文作者 : 对六
原文链接 : http://duiliuliu.github.io/2019/03/18/Java格式化时间-面试题/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

你我共勉!

微信

微信

支付宝

支付宝

留下足迹