powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не могу вытянуть дату из строки
35 сообщений из 35, показаны все 2 страниц
Не могу вытянуть дату из строки
    #39361101
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте! Столкнулся с такой проблемой в базе есть строка которая отображает год, записана в разных форматах:
06,,07/16
,06/16,07/16
07/16
08
,06/16,07/16
07/16,07/16
05,07/16
Какой алгоритм можно придумать, чтобы вытягивать месяц, год и вставлять в new DateTime(2016, 7, 1);
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361106
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
son456,
Все украдено до вас.
https://msdn.microsoft.com/ru-ru/library/h9b85w22(v=vs.110).aspx
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361108
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
son456, если нет ни какой логики(алгоритма) по которому вкрячивались эти данные, то - руками... и привет индусам...
если таки каждая строка с "датой" в формате - [mm[,mm]/]yy,... то еще можно побороться... так что на счет формата?
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361155
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во что это должно превратиться?

son45605,07/16

А это?

son45606,,07/16
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361223
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Создал программку:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Delimiter
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] formats = { "MM", ",MM/yy,MM/yy", ",M/yy,MM/yy,,", "MM/yy,MM/yy", "MM,MM/yy", "MM,,MM/yy" };
            string[] dateStrings = {"06,,07/16", ",06/16,07/16", 
                              "07/16", "08", 
                              ",06/16,07/16", "07/16,07/16","05,07/16"}; 
            DateTime dateValue;

            foreach (string dateString in dateStrings)
            {
              if (DateTime.TryParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None, 
                                    out dateValue))
               Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
                else
               Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
           }
            Console.ReadLine();
        }
    }
}


Результат
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361226
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
05,07/16
должно превратится в две даты 05/16 и 07/16
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361228
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
06,,07/16 две запятые это ошибки ввода
должно превратиться в 06/16 и 07/16
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361244
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант:
читаешь последовательно с разделителем ',' или '/'
если прочитано не ноль, то вставляешь в очередь.
если разделитель / то читаешь после него год, извлекаешь из очереди месяца и генеришь даты.

Например для "06,,07/16"
1. прочитал 06 - в очередь
2. прочитал "" - игнорируем
3. прочитал 07 - в очередь
4. прочитал год 16 из очереди извлекаем месяцы, получаем 06/16 и 07/16
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361274
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если не сложно можете привести пример кода, дело в том что я так примерно и представляю, я закодировать это не могу
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361295
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
son45605,07/16
должно превратится в две даты 05/16 и 07/16

На здоровье:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        public static DateTime[] ConvertToDate(string s)
        {
            if(string.IsNullOrEmpty(s)) return new DateTime[0];
            var rx = new Regex(@"(^|,)(?<month>\d{2})(/(?<year>\d{2}))?($|,)", RegexOptions.Compiled);
            var matches = rx.Matches(s);
            var now = DateTime.Now;
            return matches
                .Cast<Match>()
                .Select(m =>
                {
                    var yearGroup = m.Groups["year"];
                    var monthGroup = m.Groups["month"];
                    var year = yearGroup.Success ? int.Parse(yearGroup.Value) : now.Year;
                    if (year < 100)
                    {
                        year += year >= 60 ? 1900 : 2000;
                    }
                    var month = int.Parse(monthGroup.Value);
                    return new DateTime(year, month, 1);
                })
                .ToArray();
        }



Подаёшь на вход строку, получаешь коллекцию дат, возможно пустую, если в строке ничего не нашлось.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361309
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
son456,

А вот и тесты:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
        [Test]
        public void ConvertToDate_Tests()
        {
            var now = DateTime.Now;
            Assert.That(Program.ConvertToDate("06,,07/16"), Is.EquivalentTo(new[]
            {
                new DateTime(now.Year, 6, 1),
                new DateTime(2016, 7, 1),  
            }));
            Assert.That(Program.ConvertToDate(",06/16,07/16"), Is.EquivalentTo(new[]
            {
                new DateTime(2016, 6, 1),
                new DateTime(2016, 7, 1),
            }));
            Assert.That(Program.ConvertToDate("07/16"), Is.EquivalentTo(new[]
            {
                new DateTime(2016, 7, 1),
            }));
            Assert.That(Program.ConvertToDate("08"), Is.EquivalentTo(new[]
            {
                new DateTime(2016, 8, 1),
            }));
            Assert.That(Program.ConvertToDate("05,07/16"), Is.EquivalentTo(new[]
            {
                new DateTime(2016, 5, 1),
                new DateTime(2016, 7, 1),
            }));
        }



Тесты нашли косяк, вот исправленный метод, можно пользоваться:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        public static DateTime[] ConvertToDate(string s)
        {
            if(string.IsNullOrEmpty(s)) return new DateTime[0];
            var rx = new Regex(@"(^|,)(?<month>\d{2})(/(?<year>\d{2}))?", RegexOptions.Compiled);
            var matches = rx.Matches(s);
            var now = DateTime.Now;
            return matches
                .Cast<Match>()
                .Select(m =>
                {
                    var yearGroup = m.Groups["year"];
                    var monthGroup = m.Groups["month"];
                    var year = yearGroup.Success ? int.Parse(yearGroup.Value) : now.Year;
                    if (year < 100)
                    {
                        year += year >= 60 ? 1900 : 2000;
                    }
                    var month = int.Parse(monthGroup.Value);
                    return new DateTime(year, month, 1);
                })
                .ToArray();
        }
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361372
son456
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, все работает!
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361399
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я так понимаю это
Код: c#
1.
2.
08
,06/16,07/16


надо рассматривать как
Код: c#
1.
08,06/16,07/16


если я прав, то тут просто совпадение, т.к. даты из текущего года
hVostt
Код: c#
1.
2.
3.
4.
5.
6.
        [Test]
            Assert.That(Program.ConvertToDate("08"), Is.EquivalentTo(new[]
            {
                new DateTime(2016, 8, 1),
            }));
        }
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361470
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tесли я прав, то тут просто совпадение, т.к. даты из текущего года

Это было бы по меньшей мере странно.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361477
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЭто было бы по меньшей мере странно.
ИМХУ странно подразумевать что если в каком-то наборе не указан год, то считаем что год текущий. А если набор прошлогодний?
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361511
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИМХУ странно подразумевать что если в каком-то наборе не указан год, то считаем что год текущий. А если набор прошлогодний?


Если года нет, значит считается, что текущий. Потому что в строке может быть несколько дат с разными годами и алгоритм выяснения года по какому-то другому более полному значению выглядит очень нелепо. А текущий год как дефолтовый выглядит куда ни шло.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361573
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЕсли года нет, значит считается, что текущий.
Тогда уж считать что строка заполнена некорректно.
Считать умолчанием меняющееся значение это грабли какие-то. Сегодня получаем 08.16 через месяц тоже самое даст 08.17

Смысла гадать нет. Пусть ТС напишет как правильно трактовать эту строчку.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361586
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
son456Если не сложно можете привести пример кода, дело в том что я так примерно и представляю, я закодировать это не могу
как-то так
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
	class DateParser {
		Queue<Int32> months = new Queue<Int32>(); // очередь месяцев
		Boolean is_year = false; // читаемое означает год
		Int32 m = 0;

		void ParseChar(Char c) { // обработка очередного символа
			if(c >= '0' && c <= '9') {
				m = m*10 + c - '0';
			} else if(c == ',') {
				if(is_year) { // прочитан год, вывод результата
					while(months.Count != 0) {
						Console.WriteLine(new DateTime(m, months.Dequeue(), 1));
					}
					is_year = false;
				} else if(m != 0) { // прочитан месяц, постановка в очередь
					months.Enqueue(m);
				}
				m = 0;
			} else if(c == '/') {
				if(is_year) { // после года не может идти год
					throw new FormatException();
				} else if(m != 0) {
					months.Enqueue(m);
					is_year = true;
				}
				m = 0;
			} else { // неизвестный символ
				throw new FormatException();
			}
		}

		public void Parse(String[] data) { // разбор полного набора данных
			foreach(var s in data) {
				foreach(var c in s) {
					ParseChar(c);
				}
				ParseChar(',');
			}
			if(months.Count != 0) { // у последних месяцев не указан год
				throw new FormatException();
			}
		}
	}

	class Program {
        // Пример использования
        public static void Test()
        {
		    string[] dateStrings = {"06,,07/16", ",06/16,07/16", 
                        "07/16", "08", 
                        ",06/16,07/16", "07/16,07/16","05,07/16"};
		var p = new DateParser();
		p.Parse(dateStrings);
        }

...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361591
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мусор на входе - мусор на выходе
Ничего нового
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361594
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТогда уж считать что строка заполнена некорректно.

Я бы с самого начала такие "форматы" не принял в разработку.


Dima TСчитать умолчанием меняющееся значение это грабли какие-то. Сегодня получаем 08.16 через месяц тоже самое даст 08.17

Если года нет, откуда его взять тогда? А если в строке два разных года попалось, какой взять? Текущий год есть всегда. Учитывая постановку задачи, более менее вменяемое решение, которое по крайне мере работает всегда -- это брать текущий год.

К слову, код который я привёл очень простой и очень понятный, без переподвыподвертов. Исправить его сможет даже птушница.

К сожалению о твоём коде этого не скажешь. Без поллитра не подлезешь. Слишком замудрёный и сложный без видимого профита. Решать задачу надо как можно проще. Самые простые, короткие и понятные решения оказываются чаще всего наиболее эффективными и правильными.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361595
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилМусор на входе - мусор на выходе
Ничего нового

Да тут решать надо проблему уровнем выше. По голове кому-нибудь настучать и пару бездельников без извилины в голове уволить. Больше пользы будет.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361604
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЕсли года нет, откуда его взять тогда? А если в строке два разных года попалось, какой взять?
Ниоткуда. Исключение выдать и разбираться откуда бардак в исходных данных появился.

Ты же месяц не проверяешь, если написать 55 то будет исключение, зачем тогда
Код: c#
1.
var year = yearGroup.Success ? int.Parse(yearGroup.Value) : now.Year;


Ставь 0, тоже будет исключение.

hVosttК слову, код который я привёл очень простой и очень понятный, без переподвыподвертов. Исправить его сможет даже птушница.
Наверно я до уровня птушницы еще не дорос, регулярки не освоил еще

hVosttК сожалению о твоём коде этого не скажешь. Без поллитра не подлезешь. Слишком замудрёный и сложный без видимого профита.
Примитивный посимвольный парсер с конечным автоматом в стиле С с классами.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361628
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНиоткуда. Исключение выдать и разбираться откуда бардак в исходных данных появился.

Наилучшим решением было бы строгий формат даты, например dd/MM/yy. Но раз года нет, а ТС сказал, что год надо подставить, значит его надо где-то взять. Твоё решение взять год из какой-то другой даты наобум всё же хуже, чем взять однозначно текущий год и точка.


Dima TТы же месяц не проверяешь, если написать 55 то будет исключение, зачем тогда

Зачем мне проверять месяц, если это прекрасно делает new DateTime? Что даст эта дополнительная проверка, если исключение в любом случае будет?


Dima TПримитивный посимвольный парсер с конечным автоматом в стиле С с классами.

Абсолютно бессмысленное и беспощадное решение. Во многих адекватных компаниях за такое бьют по рукам. Другое дело, если вот этот участок кода задетектился, как бутылочное горлышко, и то, сильно сомневаюсь, что конечный автомат тут сильно бы помог. В общем ИМХО. Такой код писать нельзя. И тем более нельзя давать его новичкам, а ТС по определению новичек, зачем ему мозг выносить?
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361633
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНаверно я до уровня птушницы еще не дорос, регулярки не освоил еще

Я к тому, что понятный сопровождаемый код лучше для всех, в том числе для команды и компании в целом. Посимвольные парсеры может и интересная задачка, но профита кроме разминки ума в целом -- никакого. Только вред в чистом виде.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361792
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПримитивный посимвольный парсер с конечным автоматом в стиле С с классами.
регулярные выражения для того и придуманы чтоб не кодировать врукопашную конечные автомаьы
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39361793
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttПосимвольные парсеры может и интересная задачка, но профита кроме разминки ума в целом -- никакого.
скорее область применения узкая
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362069
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TПримитивный посимвольный парсер с конечным автоматом в стиле С с классами.
регулярные выражения для того и придуманы чтоб не кодировать врукопашную конечные автомаьы
Знаю, надо как-то собраться и поизучать регулярку.
hVosttЯ к тому, что понятный сопровождаемый код лучше для всех, в том числе для команды и компании в целом. Посимвольные парсеры может и интересная задачка, но профита кроме разминки ума в целом -- никакого. Только вред в чистом виде.
Я сначала думал написать почисловой парсер: число, разделитель, число, разделитель ... но букав много получилось, а посимвольный в данном случае самое то что надо.

Профит тут в производительности, он очень ощутим когда за нее из своего кармана платишь (мой случай). Можно купить за свой счет железяку помощнее, а можно обойтись оптимизацией кода.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362131
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПрофит тут в производительности, он очень ощутим когда за нее из своего кармана платишь (мой случай). Можно купить за свой счет железяку помощнее, а можно обойтись оптимизацией кода.

Не могу согласиться. Здесь даже мало-мальски ощутимого профита не получишь.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362136
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima TПрофит тут в производительности, он очень ощутим когда за нее из своего кармана платишь (мой случай). Можно купить за свой счет железяку помощнее, а можно обойтись оптимизацией кода.

Не могу согласиться. Здесь даже мало-мальски ощутимого профита не получишь.
new MyObject() это очень дорого по сравнению с вычислениями с int. В разы. Если бы в данной задаче входные данные занимали бы гигабайт, то было бы заметно.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362187
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли бы в данной задаче входные данные занимали бы гигабайт, то было бы заметно.

Мне интересно, на скольких данных ты выгадаешь хотя бы секунду времени
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362193
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tnew MyObject() это очень дорого по сравнению с вычислениями с int

Вот это кстати не понял, ты про создание объекта регекспа? Его легко можно вынести в статическое поле, кроме того, он компилируется в сборку.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362215
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажется правильным делать сначала самое простое, очевидное и читаемое решение. Потом уже по необходимости - рефакторинг, если потребуется выигрывать миллисекунды.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362221
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttМне интересно, на скольких данных ты выгадаешь хотя бы секунду времени
Кстати, как-то раз в похожей ситуации было не лень, и был сделан сравнительный тест. Вариант с регулярками, как ни странно, оказался быстрее.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362228
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttВот это кстати не понял, ты про создание объекта регекспа? Его легко можно вынести в статическое поле, кроме того, он компилируется в сборку.
Его можно однократно создать, я от том что он создает: m.Groups это куча строк.
...
Рейтинг: 0 / 0
Не могу вытянуть дату из строки
    #39362229
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Когда-то давно тоже баловался всякими парсерами. Баловался, пока не заметил, что начал писать свой собственный регексп-подобный-механизм
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не могу вытянуть дату из строки
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]