我正在尝试从“jira time notation”输入的用户输入中提取分钟数。
例如,我想实现以下结果
从研究中,我发现TimeSpan.ParseExact,但我无法弄清楚如何使用它来实现我的需要。
非常感谢所有帮助。
到目前为止我的代码:
public static int TextToMins(string TimeText)
{
CultureInfo culture = new CultureInfo("en-IE");
string[] formats = { "What goes here?" };
TimeSpan ts = TimeSpan.ParseExact(TimeText.Trim().ToLower(), formats, culture);
return Convert.ToInt32(ts.TotalMinutes);
}
答案 0 :(得分:3)
我可能会做类似这样的事情并避免与Timespan的内置解析混淆,假设每[工作]周的天数和[工作]日的[工作]小时数是Jira中的可配置值(在我们的系统上他们配置为每周5天和每天8小时。)
class JiraTimeDurationParser
{
/// <summary>
/// Jira's configured value for [working] days per week ;
/// </summary>
public ushort DaysPerWeek { get ; private set ; }
/// <summary>
/// Jira's configured value for [working] hours per day
/// </summary>
public ushort HoursPerDay { get ; private set ; }
public JiraTimeDurationParser( ushort daysPerWeek = 5 , ushort hoursPerDay = 8 )
{
if ( daysPerWeek < 1 || daysPerWeek > 7 ) throw new ArgumentOutOfRangeException( "daysPerWeek" ) ;
if ( hoursPerDay < 1 || hoursPerDay > 24 ) throw new ArgumentOutOfRangeException( "hoursPerDay" ) ;
this.DaysPerWeek = daysPerWeek ;
this.HoursPerDay = hoursPerDay ;
return ;
}
private static Regex rxDuration = new Regex( @"
^ # drop anchor at start-of-line
[\x20\t]* ((?<weeks> \d+ ) w )? # Optional whitespace, followed by an optional number of weeks
[\x20\t]* ((?<days> \d+ ) d )? # Optional whitesapce, followed by an optional number of days
[\x20\t]* ((?<hours> \d+ ) h )? # Optional whitespace, followed by an optional number of hours
[\x20\t]* ((?<minutes> \d+ ) m ) # Optional whitespace, followed by a mandatory number of minutes
[\x20\t]* # Optional trailing whitespace
$ # followed by end-of-line
" ,
RegexOptions.IgnorePatternWhitespace
) ;
public TimeSpan Parse( string jiraDuration )
{
if ( string.IsNullOrEmpty( jiraDuration ) ) throw new ArgumentOutOfRangeException("jiraDuration");
Match m = rxDuration.Match( jiraDuration ) ;
if ( !m.Success ) throw new ArgumentOutOfRangeException("jiraDuration") ;
int weeks ; bool hasWeeks = int.TryParse( m.Groups[ "weeks" ].Value , out weeks ) ;
int days ; bool hasDays = int.TryParse( m.Groups[ "days" ].Value , out days ) ;
int hours ; bool hasHours = int.TryParse( m.Groups[ "hours" ].Value , out hours ) ;
int minutes ; bool hasMinutes = int.TryParse( m.Groups[ "minutes" ].Value , out minutes ) ;
bool isValid = hasWeeks|hasDays|hasHours|hasMinutes ;
if ( !isValid ) throw new ArgumentOutOfRangeException("jiraDuration") ;
TimeSpan duration = new TimeSpan( weeks*DaysPerWeek*HoursPerDay + days*HoursPerDay + hours , minutes , 0 );
return duration ;
}
public bool TryParse( string jiraDuration , out TimeSpan timeSpan )
{
bool success ;
try
{
timeSpan = Parse(jiraDuration) ;
success = true ;
}
catch
{
timeSpan = default(TimeSpan) ;
success = false ;
}
return success ;
}
}
答案 1 :(得分:2)
一个大锤的方法,但是怎么样:
public static int TextToMins(string timeText)
{
var total = 0;
foreach (var part in timeText.Split(' '))
{
if (part[part.Length - 1] == 'h')
{
total += 60 * int.Parse(part.Trim('h'));
}
else
{
total += int.Parse(part.Trim('m'));
}
}
return total;
}
答案 2 :(得分:2)
以下代码将解析字符串:“1h”,“1h30m”,“12h 45m”,“1 h 4 m”,“1d 12h 34m 20s”,“80h”,“3000ms”,“20mins”, “1分钟”。
在每种情况下“空格都被忽略”,它支持“天,小时,分钟,秒和毫秒”,但很容易就可以添加月,周,年等等......只需在条件列表中添加正确的表达式即可。
public static TimeSpan ParseHuman(string dateTime)
{
TimeSpan ts = TimeSpan.Zero;
string currentString = ""; string currentNumber = "";
foreach (char ch in dateTime+' ')
{
currentString += ch;
if (Regex.IsMatch(currentString, @"^(days(\d|\s)|day(\d|\s)|d(\d|\s))", RegexOptions.IgnoreCase)) { ts = ts.Add(TimeSpan.FromDays(int.Parse(currentNumber))); currentString = ""; currentNumber = ""; }
if (Regex.IsMatch(currentString, @"^(hours(\d|\s)|hour(\d|\s)|h(\d|\s))", RegexOptions.IgnoreCase)) { ts = ts.Add(TimeSpan.FromHours(int.Parse(currentNumber))); currentString = ""; currentNumber = ""; }
if (Regex.IsMatch(currentString, @"^(ms(\d|\s))", RegexOptions.IgnoreCase)) { ts = ts.Add(TimeSpan.FromMilliseconds(int.Parse(currentNumber))); currentString = ""; currentNumber = ""; }
if (Regex.IsMatch(currentString, @"^(mins(\d|\s)|min(\d|\s)|m(\d|\s))", RegexOptions.IgnoreCase)) { ts = ts.Add(TimeSpan.FromMinutes(int.Parse(currentNumber))); currentString = ""; currentNumber = ""; }
if (Regex.IsMatch(currentString, @"^(secs(\d|\s)|sec(\d|\s)|s(\d|\s))", RegexOptions.IgnoreCase)) { ts = ts.Add(TimeSpan.FromSeconds(int.Parse(currentNumber))); currentString = ""; currentNumber = ""; }
if (Regex.IsMatch(ch.ToString(), @"\d")) { currentNumber += ch; currentString = ""; }
}
return ts;
}
答案 3 :(得分:1)
“这里有什么”的答案是,一个由Custom Timespan Format Strings的选项构建的字符串。如果我正确阅读文档,那么不在该列表中的字符(包括空格)必须使用\
字符进行转义或用单引号括起来。
例如,尝试m\m
解析“1m”,并h\h m\m
解析“1h 10m”。所以你的代码是:
string[] formats = { "m\m", "h\h\ m\m" };
警告:我没有尝试解析TimeSpan
个对象。但我已经完成了DateTime对象,它非常相似。所以我认为这应该有用。
答案 4 :(得分:1)
刚遇到同样的问题。这是我的解决方案(单元测试),它的价值是什么:
public static TimeSpan Parse(string s)
{
long seconds = 0;
long current = 0;
int len = s.Length;
for (int i=0; i<len; ++i)
{
char c = s[i];
if (char.IsDigit(c))
{
current = current * 10 + (int)char.GetNumericValue(c);
}
else if (char.IsWhiteSpace(c))
{
continue;
}
else
{
long multiplier;
switch (c)
{
case 's': multiplier = 1; break; // seconds
case 'm': multiplier = 60; break; // minutes
case 'h': multiplier = 3600; break; // hours
case 'd': multiplier = 86400; break; // days
case 'w': multiplier = 604800; break; // weeks
default:
throw new FormatException(
String.Format(
"'{0}': Invalid duration character {1} at position {2}. Supported characters are s,m,h,d, and w", s, c, i));
}
seconds += current * multiplier;
current = 0;
}
}
if (current != 0)
{
throw new FormatException(
String.Format("'{0}': missing duration specifier in the end of the string. Supported characters are s,m,h,d, and w", s));
}
return TimeSpan.FromSeconds(seconds);
}