#c# #asp.net #linq
#c# #asp.net #linq
Вопрос:
Как я могу преобразовать следующее во времена, зная, что значения представляют собой количество минут.
350-659, 1640-2119, 2880-3479;
The output id like is
M 5:50am - 10:59am
T 3:20am - 10:59am
W 12:00am - 9:59am
etc....
Ranges -
Mon= 0-1439
Tue = 1440-2879
Wed = 2880 - 4319
Thurs = 4321 - 5759
Fri = 5760 - 7199
Sat = 7200 - 8639
Sun = 8640 - 10079
Что у меня есть до сих пор, так это
var days = new[] { 24, 48, 72, 96, 120, 144, 168 };
var numbers = Enumerable.Range(1,7);
var hours = days.ToDictionary(x => (double)x/24, i => (int)I*60);
which outputs
Key Value
1 1440
2 2880
3 4320
4 5760
5 7200
6 8640
7 10080
Комментарии:
1. Работайте в обратном направлении, напишите функцию, которая выполняет задачу синтаксического анализа, которую вы хотите. Затем напишите функцию, которая перечисляет токены из исходного ввода. Затем напишите код, который передает токены в функцию синтаксического анализа. Затем изучите, как преобразовать этот код, скорее всего, цикл foreach, в проекцию linq. Другими словами, разберите задачу на этапы и проработайте каждый шаг по отдельности.
2. Я думаю, что кто-то некоторое время назад подумал, что это было бы хорошей идеей сделать это. Я думаю, вам также нужно было бы знать, какой сегодня день недели.
3. Кроме того, ваши сопоставления неверны. 1440 — вторник в 00:00, и то же самое для остальных.
4. преобразуйте следующее во времена — времена, когда ? На самом деле в C # нет такого понятия, как время, без даты, которая прилагается к нему. Хорошо, итак, 540 — это «9 утра в понедельник», но на какой неделе какого года вы хотите, чтобы это было?
5. Одна буква за день не сократит его. Есть два Ts и два Ss. Кажется, что вы выдвигаете требования по ходу работы.
Ответ №1:
Я вроде как вообще не понимаю вопроса, но принимаю все, что вы сказали, за чистую монету:
var times = "350-659, 1640-2119, 2880-3479;"
.Split(',') //split to string pairs like "350-659"
.Select(s => s.Split('-').Select(x => int.Parse(x)).ToArray()) //split stringpairs to two strings like "350" and "659", then parse to ints and store as an array
.Select(sa => new { //turn array ints into dates
F = new DateTime(0).AddMinutes(sa[0]), //date 0 i.e. jan 1 0001 was a monday. add minutes to it to get a time and day
T = new DateTime(0).AddMinutes(sa[1] 1) //add 1 to the end minute otherwise 659 is 10:59pm and you want 11:00am
}
)
.Select(t =>
$"{($"{t.F:ddd}"[0])} {t.F:hh':'mmtt} - {t.T:hh':'mmtt}" //format the date to a day name and pull the first character, plus format the dates to hh:mmtt format (eg 09:00AM)
);
Console.Write(string.Join("rn", times));
Если вы действительно хотите работать с этими вещами разумным образом, я рекомендую вам остановиться раньше, чем окончательный выбор, который их упорядочивает, и работать с анонимным типом t
, который содержит пару datetimes
Единственное, что в этом выводе не соответствует спецификации, это то, что AM / PM написаны в верхнем регистре. Если это вас беспокоит, подумайте:
$"{t.F:ddd}"[0] ($" {t.F:hh':'mmtt} - {t.T:hh':'mmtt}").ToLower()
Комментарии:
1. Спасибо, если вы не возражаете, если я спрошу, какое выражение вы использовали в операторе select с помощью $, я все еще новичок в LINQ
2. Это не linq, это интерполяция строк.
var x = "Hello"; var y = $"{x} world";
это более аккуратный способ записиvar x = "Hello"; var y = string.Format("{0} world", x);
, хотя вы не можете повторно использовать параметры, как в строке. Форматирование; если вы хотите что-то в интерполированной строке дважды, вам нужно записать это дважды, поэтому, например,var y = $"{(i < 1 ? "hello":"goodbye")} {(i < 1 ? "hello":"goodbye")} world"
может быть не так аккуратно, по вашему мнению, какvar y = string.Format("{0} {0} world", (i < 1 ? "hello":"goodbye")
.3. Вероятно, самое аккуратное, что можно сделать при интерполяции, — это создать переменные:
var helloOrGoodbye = (i < 1 ? "hello":"goodbye"); var y = $"{helloOrGoodbye} {helloOrGoodbye} world"
. Точно так же, как со строкой. Форматирование, заполнитель может принимать строку формата после двоеточия, поэтомуvar i = 255; var y = $"Hex is: {i:X}"
будет форматировать 255 как шестнадцатеричную строку, так же, как вызовi.ToString("X")
илиstring.Format("Hex is: {0:X}", i);
будет4. Я добавил несколько комментариев, объясняющих linq
Ответ №2:
Вы могли бы получить текущий понедельник недели и добавить минуты. Я не думаю, что вы можете сделать это в Linq напрямую.
//your timestamp
int minutes = 2345;
//get the day of week (sunday = 0)
int weekday = (int)DateTime.Now.DayOfWeek - 1;
if (DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
weekday = 6;
//get the first day of this week
DateTime firstDayOfWeek = DateTime.Now.AddDays(-1 * weekday);
//add the number of minutes
DateTime date = firstDayOfWeek.Date.AddMinutes(minutes);
Ответ №3:
Интервал времени (в отличие от абсолютного момента времени) выражается как промежуток времени. В этом случае у вас будет один временной интервал, который представляет смещение (от начала недели) до времени начала, затем другой временной интервал, который представляет смещение до времени окончания.
Вот как преобразовать вашу строку в последовательность временных интервалов.
var input = @"540-1019;1980-2459;3420-3899;4860-5339;6300-6779";
var times = input
.Split(';')
.Select(item => item.Split('-'))
.Select(pair => new
{
StartTime = new TimeSpan(hours: 0, minutes: int.Parse(pair[0]), seconds: 0),
EndTime = new TimeSpan(hours: 0, minutes: int.Parse(pair[1]), seconds: 0)
})
.ToList();
foreach (var time in times)
{
Console.WriteLine
(
@"Day: {0} Start: {1:h:mm} End: {2:h:mm}",
time.StartTime.Days,
time.StartTime,
time.EndTime
);
}
Вывод:
Day: 0 Start: 9:00 End: 16:59
Day: 1 Start: 9:00 End: 16:59
Day: 2 Start: 9:00 End: 16:59
Day: 3 Start: 9:00 End: 16:59
Day: 4 Start: 9:00 End: 16:59
Вы, конечно, можете выбрать форматирование временного интервала любым удобным для вас способом, используя соответствующую строку формата.