AM/PM обозначенный специальный случай для полудня и полуночи
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:00 или полдень. Есть ли способ создать формат, который будет учитывать этот уникальный сценарий и использовать суффикс N, когда он полдень, но сохранить стандарт A для AM и P для PM в другое время?
Обновление с возможным решением:
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
1 ответ
Я стремился к какому-то общему решению, где формат мог бы измениться как ddmm hhmmt или hmtt, и перегрузка позаботилась бы о различных форматах за исключением специального случая спецификатора "t".
Простая функция все еще может справиться с этим. Вот пример в качестве метода расширения.
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"