Премахване на отместването на часовата зона от DateTimeOffset. Премахване на отместване на часовата зона от DateTimeOffset Отместване на нулева дата sql сървър

DateTimeOffset testDateAndTime = нов DateTimeOffset(2008, 5, 1, 8, 6, 32, нов TimeSpan(1, 0, 0)); //ИЗЧИСТВАНЕ НА ВРЕМЕ И ДАТА testDateAndTime = testDateAndTime.DateTime.Date; var datesTableEntry = db.DatesTable.First(dt => dt.Id == someTestId); datesTableEntry.test= testDateAndTime; db.SaveChangesAsync();

РЕЗУЛТАТ В БАЗАТА ДАННИ: 2008-05-01 00:00:00.0000000 -04:00

Как да активирам -4:00 до +00:00 (от код преди запазване)?

Опитах:

Обществена задача SetTimeZoneOffsetToZero(DateTimeOffset dateTimeOffSetObj) ( TimeSpan zeroOffsetTimeSpan = new TimeSpan(0, 0, 0, 0, 0); return dateTimeOffSetObj.ToOffset(zeroOffsetTimeSpan); )

Той не прави нищо.

Крайната цел е просто да имате дата без отместване на времето или часовата зона. НЕ искам да преобразувам часа в друга часова зона (т.е. 00:00:00.0000000 не искам да изважда 4 часа от 00:00:00.0000000 времето и 00:00:00.0000000 да компенсира зададеното време с +00 :00 , просто искам да зададе отместването на +00:00). Искам текущата дата с нулево отместване.

Редактиране:

Ето какво можете да предложите другаде:

DateTimeOffset testDateAndTime = нов DateTimeOffset(2008, 5, 1, 8, 6, 32, нов TimeSpan(1, 0, 0)); testDateAndTime = testDateAndTime.DateTime.Date; //Нулиране на част от времето testDateAndTime = DateTime.SpecifyKind(testDateAndTime.Date, DateTimeKind.Utc); // "Нулева" компенсирана част

Бях сигурен, че SpecifyKind ще SpecifyKind моя dateTimeOffset, като например да промени И ДВАТА отместването на часа и часовата зона, но когато се тества, изглежда просто променя отместването на часовата зона, което е, което искам. Има ли проблем с това?

1 отговор

Проблемът няма нищо общо с базата данни. Ако зададете точка на прекъсване или регистрирате изход някъде, трябва да видите отместването да бъде обвързано малко след този код:

TestDateAndTime = testDateAndTime.DateTime.Date;

Нека да го разбием:

  • Започнахте с DateTimeOffset 2008-05-01T08:06:32+01:00
  • След това извикахте .DateTime, което доведе до стойност на DateTime 2008-05-01T08:06:32 с DateTimeKind.Unspecified.
  • След това извикахте .Date, което доведе до стойност на DateTime 2008-05-01T00:00:00 с DateTimeKind.Unspecified.
  • Връщате резултата в testDateAndTime, който е от тип DateTimeOffset. Това причинява имплицитно преобразуване от DateTime в DateTimeOffset който прилага местната часова зона. Във вашия случай изглежда, че отместването за тази стойност във вашата местна часова зона е -04:00, така че получената стойност е DateTimeOffset 2008-05-01T00:00:00-04:00, както описахте,

Ти каза:

Крайната цел е просто да имате дата без отместване на времето или часовата зона.

Е, понастоящем няма собствен C# тип данни, който да е просто дата без час. Има чист тип Date в пакета System.Time в corefxlab, но той не е съвсем готов за типично производствено приложение. Има LocalDate в библиотеката за време на Noda, която можете да използвате днес, но все пак ще трябва да конвертирате обратно към естествен тип, преди да запазите в базата данни. Така че междувременно най-доброто, което можете да направите, е:

  • Променете вашия SQL Server, за да използвате тип дата в това поле.
  • Във вашия .NET код използвайте DateTime с час 00:00:00 и DateTimeKind.Unspecified. Трябва да запомните да игнорирате часовата част (тъй като наистина има дати без местна полунощ в определени часови зони).
  • Променете тестовия сигнал на DateTime, а не на DateTimeOffset.

Като цяло, въпреки че DateTimeOffset е подходящ за голям брой сценарии (като събития с клеймо за време), той не е подходящ за стойности само за дата.

Искам текущата дата с нулево отместване.

Ако наистина го искате като DateTimeOffset, бихте направили:

TestDateAndTime = нов DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);

Аз обаче не съветвам това. Правейки това, вие приемате местната дата на оригиналната стойност и твърдите, че тя е в UTC. Ако първоначалното отместване е нещо различно от нула, това ще бъде невярно твърдение. Впоследствие това ще доведе до други грешки, тъй като всъщност говорите за различен момент от време (с потенциално различна дата) от този, който сте създали.

По отношение на допълнителния въпрос, зададен във вашата редакция - указването на DateTimeKind.Utc променя поведението на неявното предаване. Вместо да се използва местната часова зона, се използва UTC време, което винаги има нулево отместване. Резултатът е същият като по-ясния изглед, който дадох по-горе. Все още препоръчвам да не го правите поради същите причини.

Нека да разгледаме примера за започване от 2016-12-31T22:00:00-04:00. Според вашия подход трябва да запишете 2016-12-31T00:00:00+00:00 в базата данни. Това обаче са две различни точки във времето. Първият, нормализиран към UTC, ще бъде 2017-01-01T02:00:00+00:00, а вторият, преобразуван в друга часова зона, ще бъде 2016-12-30T20:00:00-04:00. Моля, обърнете внимание на промяната в датите при преобразуването. Това вероятно не е поведение, което бихте искали във вашето приложение.

Хуманният вариант ([трябва да се регистрирате, за да видите връзката]).

Същността на проблема е следната. Ако случайно сте разположили база данни на SQL сървър с „изместване на дата“ от 0, тогава възниква проблем, когато базата данни съдържа атрибут с тип TIME, т.е. този атрибут е зададен на 01 /01/0001 10:30:00 или дата на регистрация празна 01.01.0001 00:00:00. При запис на такива подробности не се записва.
В интернет предлагат създаване на нова база данни с отместване 2000.
Но всъщност не исках да създавам нова база. И променете пътя до базата данни за всички потребители.
След това последвах пътя къде се съхранява тази стойност в SQL. Намерих го и го смених на 2000 и всичко беше наред..
И сега стъпка по стъпка къде да се промени.

Изритайте всички потребители.

ВНИМАНИЕ!!!

1. Първо, направете резервно копие с помощта на 1C инструменти, т.е. качете го в *.dt
Това трябва да се направи преди промяна на „отместването“
Ако това не е направено, тогава в цялата ви база данни ще има препратки, документи и т.н.
където има реквизит датата ще бъде да речем 02.10.0009
КАКВО Е НЕПОЗВОЛЕНО...
Така че сте качили в *.dt

2. Отидете на SQL Server Management Studio
Намерете вашата база в списъка и натиснете знака плюс.
Намерете там папката „Таблици“ и я отворете.
Ще се отворят куп маси, отидете до дъното, намерете масата
_YearOffset, застанете върху него и изберете елемента „Отвори маса“ с десния бутон, вижте Фиг. 1
Променете стойността от 0 на 2000
Затворете SQL Server Management Studio

3. Отидете в конфигуратора и заредете предварително запазената база данни.

Ако това не е направено, тогава всички дати ще бъдат с година 0009.
След като базата данни се зареди... Можете да отидете в 1C и да се уверите, че датите са нормални.
Резултатът е, че променихме „отместването на датата от 0 до 2000“

Понякога се случва тази опция да не може да се използва по една или друга причина. След това има по-хардкор опция ([трябва да се регистрирате, за да видите връзката]):

Декларирайте курсора TablesAndFields за

ИЗБЕРЕТЕ objects.name като име на таблица, columns.name като име на колона
ОТ dbo.sysobjects катообекти
left join dbo.syscolumns като колони на objects.id = columns.id
където objects.xtype = "U" и columns.xtype = 61

отворете TablesAndFields

WHILE @@FETCH_STATUS = 0
BEGIN Exec(" актуализация"+ @TableName + "
комплект " + @ColumnName + " = ""2000- 01- 01 00:00:00" "
където " + @ColumnName + " > ""3999- 12- 31 23:59:59" "")

Това се изпълнява, докато предишното извличане е успешно.
FETCH NEXT FROM TablesAndFields в @TableName, @ColumnName
КРАЙ

затворете TablesAndFields
deallocateTablesAndFields
отивам

Преди всякакви манипулации не забравяйте да направите копия на базите данни!

Проблемът няма нищо общо с базата данни. Ако зададете точка на прекъсване или въведете изход някъде, трябва да можете да видите отместването да се прихваща малко след този код:

TestDateAndTime = testDateAndTime.DateTime.Date;

Нека да го разбием:

  • Започнахте със стойност на DateTimeOffset 2008-05-01T08:06:32+01:00
  • След това извикахте .DateTime, което доведе до стойността DateTime 2008-05-01T08:06:32 с DateTimeKind.Unspecified.
  • След това извикахте .Date, което доведе до стойност на DateTime 2008-05-01T00:00:00 с DateTimeKind.Unspecified.
  • Присвоявате резултата на testDateAndTime, който е от тип DateTimeOffset. Това причинява имплицитно прехвърляне от DateTime към DateTimeOffset - , което се прилага местенЧасова зона. Във вашия случай изглежда, че отместването за тази стойност във вашата местна часова зона е -04:00, така че получената стойност е DateTimeOffset от 2008-05-01T00:00:00-04:00, както описахте.

Ти каза:

Крайната цел е просто да имате дата без отместване на час или часова зона.

Е, има понастоящемне е собствен C# тип данни, който е просто дата без време. Има чист тип дата в Системно времепакет в corefxlab, но все още не е напълно готов за типично производствено приложение. Има LocalDate в библиотеката Noda Time, която можете да използвате днес, но все пак ще трябва да конвертирате обратно към собствен тип, преди да запазите в базата данни. Така че междувременно най-доброто, което можете да направите, е:

  • Променете вашия SQL Server, за да използвате тип дата в полето.
  • Във вашия .NET код използвайте DateTime с час 00:00:00 и DateTimeKind.Unspecified. Трябва да запомните да игнорирате часовата част (тъй като наистина има дати без местна полунощ в определени часови зони).
  • Променете тестовото предложение да бъде DateTime, а не DateTimeOffset.

Като цяло, докато DateTimeOffset е подходящ за голям брой сценарии (напр времеви отпечатъцисъбития), не се вписва добре за стойности само за дата.

Искам текущата дата с нулево отместване.

Ако ти наистина искамтова е като DateTimeOffset, можете да направите:

TestDateAndTime = нов DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);

Въпреки това не препоръчвам да правите това. Правейки това, вие вземате местендатата на първоначалната стойност и твърдят, че е в UTC. Ако първоначалното отместване е нещо различно от нула, това ще бъде невярно твърдение. Впоследствие това ще доведе до други грешки, тъй като всъщност говорите за различен момент от време (с потенциално различна дата) от този, който сте създали.

По отношение на допълнителния въпрос, зададен към вашия съвет. Указването на DateTimeKind.Utc променя поведението на неявното предаване. Вместо да се използва местната часова зона, се използва UTC време, което винаги има нулево отместване. Резултатът е същият като по-ясния изглед, който дадох по-горе. Все още препоръчвам да не го правите поради същите причини.

Помислете за пример, започващ с 2016-12-31T22:00:00-04:00. Според вашия подход трябва да запишете 2016-12-31T00:00:00+00:00 в базата данни. Това обаче са две различни точки във времето. Първият, нормализиран към UTC, ще бъде 2017-01-01T02:00:00+00:00, а вторият, преобразуван в друга часова зона, ще бъде 2016-12-30T20:00:00-04:00. Моля, обърнете внимание на промяната в датите при преобразуването. Това вероятно не е поведение, което бихте искали във вашето приложение.

Публикации по темата