Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не могу вытянуть дату из строки / 25 сообщений из 35, страница 1 из 2
06.12.2016, 11:50
    #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
06.12.2016, 11:56
    #39361106
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
son456,
Все украдено до вас.
https://msdn.microsoft.com/ru-ru/library/h9b85w22(v=vs.110).aspx
...
Рейтинг: 0 / 0
06.12.2016, 11:58
    #39361108
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
son456, если нет ни какой логики(алгоритма) по которому вкрячивались эти данные, то - руками... и привет индусам...
если таки каждая строка с "датой" в формате - [mm[,mm]/]yy,... то еще можно побороться... так что на счет формата?
...
Рейтинг: 0 / 0
06.12.2016, 13:01
    #39361155
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Во что это должно превратиться?

son45605,07/16

А это?

son45606,,07/16
...
Рейтинг: 0 / 0
06.12.2016, 14:30
    #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
06.12.2016, 14:32
    #39361226
son456
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
05,07/16
должно превратится в две даты 05/16 и 07/16
...
Рейтинг: 0 / 0
06.12.2016, 14:33
    #39361228
son456
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
06,,07/16 две запятые это ошибки ввода
должно превратиться в 06/16 и 07/16
...
Рейтинг: 0 / 0
06.12.2016, 14:51
    #39361244
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Как вариант:
читаешь последовательно с разделителем ',' или '/'
если прочитано не ноль, то вставляешь в очередь.
если разделитель / то читаешь после него год, извлекаешь из очереди месяца и генеришь даты.

Например для "06,,07/16"
1. прочитал 06 - в очередь
2. прочитал "" - игнорируем
3. прочитал 07 - в очередь
4. прочитал год 16 из очереди извлекаем месяцы, получаем 06/16 и 07/16
...
Рейтинг: 0 / 0
06.12.2016, 15:10
    #39361274
son456
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Если не сложно можете привести пример кода, дело в том что я так примерно и представляю, я закодировать это не могу
...
Рейтинг: 0 / 0
06.12.2016, 15:35
    #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
06.12.2016, 15:45
    #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
06.12.2016, 16:42
    #39361372
son456
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Спасибо, все работает!
...
Рейтинг: 0 / 0
06.12.2016, 17:07
    #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
06.12.2016, 19:11
    #39361470
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Dima Tесли я прав, то тут просто совпадение, т.к. даты из текущего года

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


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

Смысла гадать нет. Пусть ТС напишет как правильно трактовать эту строчку.
...
Рейтинг: 0 / 0
07.12.2016, 08:29
    #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
07.12.2016, 08:55
    #39361591
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Мусор на входе - мусор на выходе
Ничего нового
...
Рейтинг: 0 / 0
07.12.2016, 09:01
    #39361594
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Dima TТогда уж считать что строка заполнена некорректно.

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


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

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

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

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

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

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


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

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

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

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


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

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


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

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

Я к тому, что понятный сопровождаемый код лучше для всех, в том числе для команды и компании в целом. Посимвольные парсеры может и интересная задачка, но профита кроме разминки ума в целом -- никакого. Только вред в чистом виде.
...
Рейтинг: 0 / 0
07.12.2016, 13:41
    #39361792
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не могу вытянуть дату из строки
Dima TПримитивный посимвольный парсер с конечным автоматом в стиле С с классами.
регулярные выражения для того и придуманы чтоб не кодировать врукопашную конечные автомаьы
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Не могу вытянуть дату из строки / 25 сообщений из 35, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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