Мені було цікаво, які саме принципи роботи двох властивостей. Я знаю, що другий є універсальним і в основному не стосується часових поясів, але чи може хтось детально пояснити, як вони працюють і який слід використовувати в якому сценарії?
Мені було цікаво, які саме принципи роботи двох властивостей. Я знаю, що другий є універсальним і в основному не стосується часових поясів, але чи може хтось детально пояснити, як вони працюють і який слід використовувати в якому сценарії?
Відповіді:
DateTime.UtcNow повідомляє вам дату та час, як це було б у універсальний координований час, який також називають часовим поясом середнього часового режиму Грінвіч - в основному, як це було б, якби ви були в Лондонській Англії, але не влітку. DateTime.Now вказує дату та час, як вони відображатимуться для когось у вашому поточному регіоні.
Я рекомендую використовувати DateTime.Now
кожен раз, коли ви показуєте побачення людині - таким чином вони зручні зі значенням, яке вони бачать - це те, що вони можуть легко порівняти з тим, що вони бачать на годиннику чи годиннику. Використовуйте, DateTime.UtcNow
коли ви хочете зберігати дати або використовувати їх для наступних розрахунків таким чином (у моделі клієнт-сервер) ваші розрахунки не плутаються клієнтами в різних часових поясах від вашого сервера або один від одного.
Це дійсно досить просто, тому я думаю, це залежить від того, яка ваша аудиторія та де вони живуть.
Якщо ви не використовуєте Utc, ви повинні знати часовий пояс людини, якій ви показуєте дати та час, інакше ви скажете їм, що сталося о 15:00 у системний або серверний час, коли це дійсно сталося о 17:00, де вони трапляються жити.
Ми використовуємо це DateTime.UtcNow
тому, що у нас є глобальна аудиторія в Інтернеті, і тому, що я не вважаю за потрібне кожним користувачем заповнювати форму із зазначенням того, в якому часовому поясі вони живуть.
Ми також відображаємо відносний час (2 години тому, 1 день тому і т. Д.), Поки публікація не стане достатньою, щоб час був "тим самим", незалежно від того, де ви живете на Землі.
Також врахуйте різницю у виконанні; DateTime.UtcNow
це десь у 30 разів швидше DateTime.Now
, тому що внутрішньо DateTime.Now
робиться багато коригувань часового поясу (ви можете легко перевірити це за допомогою Reflector).
Тому НЕ використовуйте DateTime.Now
для відносних вимірювань часу.
Одна з основних для розуміння концепція в .NET є те , що в даний час не є в даний час по всій землі незалежно від того , в якому часовому поясі ви знаходитесь в так що якщо ви завантажте змінну с. DateTime.Now
Або DateTime.UtcNow
-. Призначення ідентично * Ваш DateTime
об'єкт знає , що часовий пояс , ви перебуваєте в і враховує це незалежно від призначення.
Корисність DateTime.UtcNow
корисна для підрахунку дат через межі літнього часу. Тобто в місцях, які беруть участь у переході на літній час, інколи буває 25 годин з полудня до полудня наступного дня, а іноді - 23 години між полуднем та полуднем наступного дня. Якщо ви хочете правильно визначити кількість годин з часу А та часу В, вам потрібно спочатку перевести кожну їхню еквівалентну UTC, перш ніж обчислити значення TimeSpan
.
Про це висвітлюється повідомлення в блозі, який я писав, що далі пояснює TimeSpan
, і включає посилання на ще більш обширну статтю MS на цю тему.
* Пояснення: будь-яке завдання буде зберігати поточний час. Якщо ви повинні були завантажити дві змінних один через , DateTime.Now()
а інші з допомогою DateTime.UtcNow()
до TimeSpan
різниці між ними будуть мілісекунди, а не годинник , які передбачають ви перебуваєте в часовому поясі годин їзди від GMT. Як зазначалося нижче, при виведенні їх String
значень відображатимуться різні рядки.
Це гарне запитання. Я відроджую це, щоб трохи детальніше розповісти про те, як .Net поводиться з різними Kind
значеннями. Як зазначає @Jan Zich, це насправді критично важлива властивість і встановлюється по-різному залежно від того, використовуєте ви Now
чи UtcNow
.
Внутрішня дата зберігається так, Ticks
що (всупереч відповіді @Carl Camera) відрізняється залежно від того, використовуєте ви Now
чи UtcNow
.
DateTime.UtcNow
поводиться як інші мови. Він встановлює Ticks
значення на основі GMT. Він також налаштований Kind
на Utc
.
DateTime.Now
змінює Ticks
значення на те, яке воно було б, якби ваш час доби знаходився у часовому поясі GMT . Він також налаштований Kind
на Local
.
Якщо ви відстали на 6 годин (GMT-6), ви отримаєте час GMT з 6 годин тому. .Net насправді ігнорує Kind
та ставиться до цього часу так, ніби це було 6 годин тому, навіть якщо це повинно бути "зараз". Це збільшується ще більше, якщо ви створюєте DateTime
екземпляр, а потім змініть свій часовий пояс і спробуйте його використовувати.
Екземпляри DateTime з різними значеннями 'Kind' НЕ сумісні.
Давайте подивимось на якийсь код ...
DateTime utc = DateTime.UtcNow;
DateTime now = DateTime.Now;
Debug.Log (utc + " " + utc.Kind); // 05/20/2015 17:19:27 Utc
Debug.Log (now + " " + now.Kind); // 05/20/2015 10:19:27 Local
Debug.Log (utc.Ticks); // 635677391678617830
Debug.Log (now.Ticks); // 635677139678617840
now = now.AddHours(1);
TimeSpan diff = utc - now;
Debug.Log (diff); // 05:59:59.9999990
Debug.Log (utc < now); // false
Debug.Log (utc == now); // false
Debug.Log (utc > now); // true
Debug.Log (utc.ToUniversalTime() < now.ToUniversalTime()); // true
Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime()); // false
Debug.Log (utc.ToUniversalTime() > now.ToUniversalTime()); // false
Debug.Log (utc.ToUniversalTime() - now.ToUniversalTime()); // -01:00:00.0000010
Як ви бачите тут, порівняння та математичні функції не автоматично перетворюються на сумісні часи. Timespan
Мав майже одну годину, але замість цього був майже 6. «UTC <зараз» має бути правдою (я навіть додав годину , щоб переконатися), але по - , як і раніше помилково.
Ви також можете побачити "роботу навколо", яка полягає в тому, щоб просто перетворити на універсальний час в будь-якому місці, яке Kind
не є однаковим.
Моя пряма відповідь на питання узгоджується з рекомендацією прийнятої відповіді про те, коли використовувати кожну. Ви завжди повинні намагатися працювати з DateTime
об'єктами, які є Kind=Utc
, за винятком під час вводу-виводу (відображення та розбір). Це означає, що ви майже завжди повинні користуватися DateTime.UtcNow
, за винятком випадків, коли ви створюєте об’єкт просто для його відображення та відкидаєте його відразу.
DateTime поняття не має, що таке часові пояси. Це завжди передбачає, що ви знаходитесь у свій місцевий час. UtcNow означає лише "Відняти мій часовий пояс із часу".
Якщо ви хочете використовувати дати, відомі часовому поясу, використовуйте DateTimeOffset , який представляє дату / час із часовим поясом. Мені довелося навчитися тому важкому шляху.
"Проста" відповідь на питання:
DateTime.Now повертає значення DateTime, що представляє поточний, системний час (у будь-якому часовому поясі працює система). DateTime.Kind майно буде DateTimeKind.Local
DateTime.UtcNow повертає значення DateTime, що представляє поточний універсальний координований час (також UTC), яке буде однаковим, незалежно від часового поясу системи. DateTime.Kind майно буде DateTimeKind.Utc
Лише невелике доповнення до наведених вище пунктів: структура DateTime також містить маловідоме поле під назвою Kind (принаймні, я про це давно не знав). Це в основному лише прапор, який вказує, чи місцевий час або UTC; він не визначає реального зміщення від UTC за місцевим часом. Крім того, що вказує на те, з якими намірами була побудована стука, це також впливає на те, як працюють методи ToUniversalTime () та ToLocalTime () .
Трохи запізнюємось на вечірку, але я знайшов ці два посилання (4guysfromrolla) дуже корисними:
Використання координованого універсального часу (UTC) для зберігання значень дати / часу
Поради щодо зберігання та відображення дат та часу в різних часових зонах
DateTime.UtcNow - це безперервна однозначна часова шкала, тоді як DateTime.Now не є безперервною або однозначною. Основна причина - літній час, який не застосовується до UTC. Тож UTC ніколи не стрибає вперед або назад години, тоді як місцевий час (DateTime.Now). І коли вона стрибає назад, однакове значення часу виникає двічі.
DateTime.UtcNow - це універсальна шкала часу, опускаючи літній час. Тож UTC ніколи не змінюється через DST.
Але, DateTime.Now не є безперервним або однозначним, оскільки він змінюється відповідно до DST. Що означає DateTime.Now, однакове значення часу може виникати двічі, залишаючи клієнтів у заплутаному стані.
Коли вам потрібен місцевий час для роботи машини, на якій працює ваша програма (наприклад, CEST для Європи), використовуйте Асистент. Якщо ви хочете універсальний час - UtcNow. Це лише питання ваших уподобань - можливо, зробивши локальний веб-сайт / окрему програму, яку ви хочете використовувати час, який має користувач - так це впливає його налаштування часового поясу - DateTime.Now.
Пам'ятайте лише, що для веб-сайту це налаштування часового поясу сервера. Отже, якщо ви показуєте користувачеві час, або отримайте його бажаний часовий пояс і змістіть час (просто збережіть час Utc у базі даних та змініть його) або вкажіть, що це UTC. Якщо ви забудете це зробити, користувач може побачити щось на зразок: опубліковано 3 мінуси тому, а потім поруч із ним час у майбутньому :)
Велика різниця :) полягає в тому, що DateTime.Now не підтримується в SharePoint Workflow, ви повинні використовувати DateTime.UtcNow