AM/PM 中午和午夜的指定特殊情况
AM/PM designatior special case for noon and midnight
VB2012:我正在从遗留系统读取数据。其中一个字段是时间,我正在将其读入 DateTime 变量。我使用 "hhmmt" 格式来解析带有 DateTime.ParseExact 的日期。我唯一的问题是遗留系统显示 A 代表 AM,P 代表 PM,N 代表中午。嗯,.NET 不喜欢 N 指示符,所以我检测到它并将其更改为 P。效果很好。
003 0300 AAABBB 845A 1200N
005 1400 CCCDDD 1055A 240P
007 7000 EEEFFF 306P 531P
现在我做一些处理并将数据打印到一个文件中。我想以旧系统中打印的格式打印时间。我的第一个想法是使用自定义 DateTimeFormatInfo
Dim info As New DateTimeFormatInfo
info.PMDesignator = "N"
并将其作为 IFormatProvider
提供给我的字符串格式化程序
trip.ArriveTime.ToString("hmmt", info)
但我意识到设置 DateTimeFormatInfo 是静态的,当时间是 12:00P 或中午时不会有任何用处。有什么方法可以创建一种格式来解决这种独特的情况,并在中午时使用 N 后缀,但在其他时间保持标准 A 表示上午,P 表示下午?
更新可能的解决方案:
Imports System.Text.RegularExpressions
Imports System.Globalization
Module mdlExtensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFormat(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function ToLegacy(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
'setup the master DateTimeFormatInfo
Dim ci As CultureInfo = CType(provider, CultureInfo)
Dim mstrDtfi As DateTimeFormatInfo
If provider Is Nothing Then
'designate a new DateTimeFormatInfo class if Nothing was passed in
mstrDtfi = New DateTimeFormatInfo
Else
'get a reference to the DateTimeFormatInfo class of the FormatProvider that was passed in
mstrDtfi = ci.DateTimeFormat
End If
'check to see if the time is noon and set a new PMDesignator if it is
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
mstrDtfi.PMDesignator = "NN"
End If
'check to see if the time is midnight and set a new AMDesignator if it is
If dt.TimeOfDay = New TimeSpan(0, 0, 0) Then
mstrDtfi.AMDesignator = "MM"
End If
'now format the date string with the proper provider
Dim formattedDate As String
If provider Is Nothing Then
formattedDate = dt.ToString(fmt, mstrDtfi)
Else
formattedDate = dt.ToString(fmt, ci)
End If
Return formattedDate
End Function
End Module
I was aiming for something of a generic solution where the format could change like ddmm hhmmt or hmtt and the overload would take care of the various formats except for the special case of the "t" specifier.
一个简单的函数仍然可以处理这个问题。这是一个扩展方法的例子。
Module Extensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFmt(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
End Module
?#12:00#.LegacyFmt("hmmt", Globalization.CultureInfo.InvariantCulture)
"1200N"
?now.LegacyFmt("ddmm")
"2551"
?#2:01#.LegacyFmt("hmmt")
?#12:00#.LegacyFmt("hmtt")
"120N"
"201A"
?#2:01#.LegacyFmt("hmtt")
"21AM"
VB2012:我正在从遗留系统读取数据。其中一个字段是时间,我正在将其读入 DateTime 变量。我使用 "hhmmt" 格式来解析带有 DateTime.ParseExact 的日期。我唯一的问题是遗留系统显示 A 代表 AM,P 代表 PM,N 代表中午。嗯,.NET 不喜欢 N 指示符,所以我检测到它并将其更改为 P。效果很好。
003 0300 AAABBB 845A 1200N
005 1400 CCCDDD 1055A 240P
007 7000 EEEFFF 306P 531P
现在我做一些处理并将数据打印到一个文件中。我想以旧系统中打印的格式打印时间。我的第一个想法是使用自定义 DateTimeFormatInfo
Dim info As New DateTimeFormatInfo
info.PMDesignator = "N"
并将其作为 IFormatProvider
提供给我的字符串格式化程序trip.ArriveTime.ToString("hmmt", info)
但我意识到设置 DateTimeFormatInfo 是静态的,当时间是 12:00P 或中午时不会有任何用处。有什么方法可以创建一种格式来解决这种独特的情况,并在中午时使用 N 后缀,但在其他时间保持标准 A 表示上午,P 表示下午?
更新可能的解决方案:
Imports System.Text.RegularExpressions
Imports System.Globalization
Module mdlExtensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFormat(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function ToLegacy(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
'setup the master DateTimeFormatInfo
Dim ci As CultureInfo = CType(provider, CultureInfo)
Dim mstrDtfi As DateTimeFormatInfo
If provider Is Nothing Then
'designate a new DateTimeFormatInfo class if Nothing was passed in
mstrDtfi = New DateTimeFormatInfo
Else
'get a reference to the DateTimeFormatInfo class of the FormatProvider that was passed in
mstrDtfi = ci.DateTimeFormat
End If
'check to see if the time is noon and set a new PMDesignator if it is
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
mstrDtfi.PMDesignator = "NN"
End If
'check to see if the time is midnight and set a new AMDesignator if it is
If dt.TimeOfDay = New TimeSpan(0, 0, 0) Then
mstrDtfi.AMDesignator = "MM"
End If
'now format the date string with the proper provider
Dim formattedDate As String
If provider Is Nothing Then
formattedDate = dt.ToString(fmt, mstrDtfi)
Else
formattedDate = dt.ToString(fmt, ci)
End If
Return formattedDate
End Function
End Module
I was aiming for something of a generic solution where the format could change like ddmm hhmmt or hmtt and the overload would take care of the various formats except for the special case of the "t" specifier.
一个简单的函数仍然可以处理这个问题。这是一个扩展方法的例子。
Module Extensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFmt(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
End Module
?#12:00#.LegacyFmt("hmmt", Globalization.CultureInfo.InvariantCulture)
"1200N"
?now.LegacyFmt("ddmm")
"2551"
?#2:01#.LegacyFmt("hmmt")
?#12:00#.LegacyFmt("hmtt")
"120N"
"201A"
?#2:01#.LegacyFmt("hmtt")
"21AM"