Я заинтересован в использовании NLog в моем проекте C# и нашел его замечательным, но
В моей стране Клиенты работают с «Персидским календарем».
Как вы знаете, Microsoft разработала библиотеку для поддержки имени «C# Persian Calendar class».
мне нужен персидской формат даты календаря в двух местах
1-Message Отметка времени
Имя 2-Дата на основе файла
Как заставить NLog использовать «C# персидский календарь класс» в указанных выше использований?
БлагодаряNLog use Persian Calendar Формат даты
ответ
Вам необязательно изменять источник NLog и самостоятельно его строить. Вероятно, вы могли бы написать свой собственный PersianDateLayoutRenderer. Тогда просто настроить NLog на использование средства рендеринга макета, а не на встроенный рендеринг макетов NLog. Когда вы переходите на новую версию NLog, ваш рендеринг макета должен работать.
Вот пример, который сочетает в себе LongDateLayoutRenderer NLog и .NET Persian Calendar. Я не знаю, доступно ли форматирование для персидских дат, поэтому я просто закодировал формат.
Вы можете настроить это в файле NLog.config с помощью $ {persianlongdate}, а не $ {shortdate}, $ {longdate} или $ {date}.
Я не пытался строить или запускать это, но он должен быть довольно близко. Вы можете легко изменить его, чтобы использовать Jon's Noda Time, если вы решите попробовать этот маршрут.
Вы можете найти источник для LongDateLayoutRenderer NLog (и DateLayoutRenderer и ShortDateLayoutRenderer) здесь:
https://github.com/NLog/NLog/blob/master/src/NLog/LayoutRenderers
namespace MyLayoutRenderers
{
using System.ComponentModel;
using System.Globalization;
using System.Text;
using NLog.Config;
[LayoutRenderer("persianlongdate")]
[ThreadAgnostic]
public class PersianSLongDateLayoutRenderer : LayoutRenderer
{
PersianCalendar pc = new PersianCalendar();
/// <summary>
/// Gets or sets a value indicating whether to output UTC time instead of local time.
/// </summary>
/// <docgen category='Rendering Options' order='10' />
[DefaultValue(false)]
public bool UniversalTime { get; set; }
/// <summary>
/// Renders the current short date string (yyyy-MM-dd) and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
DateTime ts = logEvent.TimeStamp;
//Not sure if UniversalTime makes sense for PersianCalendar. Do you?
if (this.UniversalTime)
{
ts = ts.ToUniversalTime();
}
builder.Append(String.Format("{0}-{1}-{2}-{3}:{4}-{5}-{6}",
pc.GetDayOfWeek(ts),
pc.GetMonth(ts),
pc.GetDayOfMonth(ts),
pc.GetYear(ts),
pc.GetHour(ts),
pc.GetMinute(ts),
pc.GetSecond(ts));
}
}
}
Удачи!
Есть две трудности с этим:
- Вы должны были бы работать, как форматирование выполняется в обоих этих случаях, и посмотреть, как вы можете настроить его, например, указав другую культуру или форматированию делегат
- Персидский календарь не является в настоящее время дополнительный календаря для любой культуры, поэтому использование
DateTime.ToString
не будет работать в любом случае :(
Вам обязательно нужно посмотреть в исходный код (или, по крайней мере, документация) для NLog, чтобы узнать, есть ли способ настройки форматирования. Как только вы разработали способ выполнения своего собственного кода, например, путем написания собственного подкласса, потенциально - вы Вам нужно будет выяснить, как сделать фактическое форматирование.
Вы можете сделать это с помощью BCL, позвонить в PersianCalendar
и делает простое числовое форматирование. Или вы можете использовать мою библиотеку Noda Time, которая также поддерживает персидский календарь (начиная с Noda Time 1.3). Вам нужно что-то вроде:
var gregorian = new LocalDate(2014, 11, 6); // Or whatever
var persian = gregorian.WithCalendar(CalendarSystem.GetPersianCalendar());
var text = persian.ToString("yyyy-MM-dd"); // Or create a LocalDatePattern
Спасибо, Как я понимаю, я должен использовать исходный код NLog вместо lib и реализовывать/изменять/добавлять персидские форматы. Это хорошо, но в каждом выпуске NLog я должен снова использовать источник. Но это единственный способ до сих пор. Еще раз спасибо за советы. –
@MohTarvirdi: В идеале вы бы подумали над тем, чтобы сделать его достаточно гибким, чтобы вы могли внести свой код (который не был бы специфичен для PersianCalendar) обратно в NLog, а затем в вашем коде будет только определенная часть PersianCalendar, которая тогда работать через несколько версий NLog. Но это будет зависеть от результатов вашего исследования того, насколько гибкий NLog уже есть. –
Отлично, спасибо большое. но он должен быть зарегистрирован сначала с помощью >> NLog.Config.ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition ("persiandate", typeof (PersianDateLayoutRenderer)); <<, но я не могу предотвратить двойную регистрацию с помощью >> if (! NLog.Config .ConfigurationItemFactory.Default.LayoutRenderers.AllRegisteredItems.ContainsKey ("persianlongdate")) << Спасибо снова –