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"
Другие вопросы по тегам